Skip to content

Commit 218dd6d

Browse files
authored
feat: initial libvirt domain module for provider v0.9.x (#1)
1 parent 3d371fb commit 218dd6d

12 files changed

Lines changed: 607 additions & 0 deletions

File tree

.checkov.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
soft-fail: true
2+
framework:
3+
- terraform
4+
skip-check:
5+
- CKV_TF_1 # Ensure Terraform module sources use a commit hash
6+
- CKV_TF_2 # Ensure Terraform module sources use a tag with a version number

.github/workflows/ci.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ['v*']
7+
pull_request:
8+
branches: [main]
9+
10+
permissions:
11+
contents: write
12+
13+
jobs:
14+
test:
15+
name: Pre-commit Tests
16+
runs-on: ubuntu-latest
17+
container:
18+
image: ghcr.io/makeitworkcloud/runner:latest
19+
steps:
20+
- name: Checkout
21+
uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0
24+
25+
- name: Initialize OpenTofu
26+
run: tofu init -backend=false
27+
28+
- name: Run tests
29+
run: make test
30+
31+
release:
32+
name: Create Release
33+
runs-on: ubuntu-latest
34+
needs: [test]
35+
if: startsWith(github.ref, 'refs/tags/v')
36+
steps:
37+
- name: Checkout
38+
uses: actions/checkout@v4
39+
40+
- name: Create GitHub Release
41+
uses: softprops/action-gh-release@v2
42+
with:
43+
generate_release_notes: true

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# vim swap files
2+
**/*.sw[po]
3+
4+
# Terraform state and lock files
5+
**/.terraform.lock.hcl
6+
**/.terraform
7+
8+
# IDE Folders
9+
**/.vscode
10+
11+
# Mac Finder cache
12+
**/.DS_Store

.pre-commit-config.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
repos:
2+
- repo: https://github.com/pre-commit/pre-commit-hooks
3+
rev: v6.0.0
4+
hooks:
5+
- id: check-case-conflict
6+
- id: check-merge-conflict
7+
- id: check-symlinks
8+
- id: check-vcs-permalinks
9+
- id: destroyed-symlinks
10+
- id: detect-private-key
11+
- id: mixed-line-ending
12+
- id: trailing-whitespace
13+
- repo: https://github.com/antonbabenko/pre-commit-terraform
14+
rev: v1.104.0
15+
hooks:
16+
- id: terraform_validate
17+
args:
18+
- --hook-config=--retry-once-with-cleanup=true
19+
- --args=-no-color
20+
- --tf-init-args=-reconfigure
21+
- --tf-init-args=-upgrade
22+
- id: terraform_tflint
23+
args:
24+
- --args=--minimum-failure-severity=error
25+
- --args=--config=__GIT_WORKING_DIR__/.tflint.hcl
26+
- id: terraform_checkov
27+
args:
28+
- --args=--config-file __GIT_WORKING_DIR__/.checkov.yml
29+
- id: terraform_fmt
30+
args:
31+
- --args=-no-color
32+
- --args=-diff
33+
- --args=-recursive
34+
- id: terraform_docs
35+
args:
36+
- --args=--config=.terraform-docs.yml

.terraform-docs.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
formatter: "markdown"
2+
3+
output:
4+
file: "README.md"
5+
mode: inject
6+
7+
settings:
8+
color: false
9+
lockfile: false
10+
11+
sort:
12+
enabled: true
13+
by: name
14+
15+
recursive:
16+
enabled: false

.tflint.hcl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
plugin "terraform" {
2+
enabled = true
3+
preset = "recommended"
4+
}
5+
6+
config {
7+
call_module_type = "local"
8+
force = false
9+
disabled_by_default = false
10+
}

Makefile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
SHELL := /bin/bash
2+
TERRAFORM := $(shell which tofu)
3+
4+
.PHONY: help init test pre-commit-check-deps pre-commit-install-hooks
5+
6+
help:
7+
@echo "Terraform Module targets"
8+
@echo "------------------------"
9+
@echo
10+
@echo "\thelp: show this help text"
11+
@echo "\tinit: run 'terraform init' (no backend)"
12+
@echo "\ttest: run pre-commit checks"
13+
@echo
14+
@echo "One-time repo init targets"
15+
@echo "--------------------------"
16+
@echo
17+
@echo "\tpre-commit-install-hooks: install pre-commit hooks"
18+
@echo "\tpre-commit-check-deps: check pre-commit dependencies"
19+
@echo
20+
21+
init:
22+
@${TERRAFORM} init -backend=false -upgrade
23+
24+
test: .git/hooks/pre-commit
25+
@pre-commit run -a
26+
27+
DEPS_PRE_COMMIT=$(shell which pre-commit || echo "pre-commit not found")
28+
DEPS_TERRAFORM_DOCS=$(shell which terraform-docs || echo "terraform-docs not found")
29+
DEPS_TFLINT=$(shell which tflint || echo "tflint not found")
30+
DEPS_CHECKOV=$(shell which checkov || echo "checkov not found")
31+
DEPS_JQ=$(shell which jq || echo "jq not found")
32+
pre-commit-check-deps:
33+
@echo "Checking for pre-commit and its dependencies:"
34+
@echo " pre-commit: ${DEPS_PRE_COMMIT}"
35+
@echo " terraform-docs: ${DEPS_TERRAFORM_DOCS}"
36+
@echo " tflint: ${DEPS_TFLINT}"
37+
@echo " checkov: ${DEPS_CHECKOV}"
38+
@echo " jq: ${DEPS_JQ}"
39+
@echo ""
40+
41+
pre-commit-install-hooks: .git/hooks/pre-commit
42+
43+
.git/hooks/pre-commit: pre-commit-check-deps
44+
@pre-commit install --install-hooks

README.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# terraform-libvirt-domain
2+
3+
Terraform module for creating libvirt domains (VMs) with cloud-init and optional Ansible Automation Platform integration.
4+
5+
## Usage
6+
7+
```hcl
8+
module "vm" {
9+
source = "git::https://github.com/makeitworkcloud/terraform-libvirt-domain.git?ref=v1.0.0"
10+
11+
name = "my-vm"
12+
description = "My virtual machine"
13+
vcpu = 2
14+
memory = 4096
15+
16+
cloudinit_meta_data_template = file("${path.module}/templates/meta-data.tpl")
17+
cloudinit_meta_data_vars = { hostname = "my-vm" }
18+
cloudinit_user_data_template = file("${path.module}/templates/user-data.tpl")
19+
cloudinit_user_data_vars = {}
20+
cloudinit_network_config_template = file("${path.module}/templates/network-config.tpl")
21+
cloudinit_network_config_vars = { ip_address = "192.168.1.100" }
22+
23+
private_ip_addr = "192.168.1.100"
24+
proxyhost = "bastion.example.com"
25+
}
26+
```
27+
28+
<!-- BEGIN_TF_DOCS -->
29+
## Requirements
30+
31+
| Name | Version |
32+
|------|---------|
33+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3 |
34+
| <a name="requirement_libvirt"></a> [libvirt](#requirement\_libvirt) | >= 0.9.0 |
35+
36+
## Providers
37+
38+
| Name | Version |
39+
|------|---------|
40+
| <a name="provider_aap"></a> [aap](#provider\_aap) | n/a |
41+
| <a name="provider_libvirt"></a> [libvirt](#provider\_libvirt) | >= 0.9.0 |
42+
43+
## Modules
44+
45+
No modules.
46+
47+
## Resources
48+
49+
| Name | Type |
50+
|------|------|
51+
| aap_host.host | resource |
52+
| aap_job.job | resource |
53+
| [libvirt_cloudinit_disk.commoninit](https://registry.terraform.io/providers/dmacvicar/libvirt/latest/docs/resources/cloudinit_disk) | resource |
54+
| [libvirt_domain.vm](https://registry.terraform.io/providers/dmacvicar/libvirt/latest/docs/resources/domain) | resource |
55+
| [libvirt_volume.boot](https://registry.terraform.io/providers/dmacvicar/libvirt/latest/docs/resources/volume) | resource |
56+
| [libvirt_volume.cloudinit](https://registry.terraform.io/providers/dmacvicar/libvirt/latest/docs/resources/volume) | resource |
57+
| [libvirt_volume.extra](https://registry.terraform.io/providers/dmacvicar/libvirt/latest/docs/resources/volume) | resource |
58+
| aap_inventory.inventory | data source |
59+
| aap_job_template.job_template | data source |
60+
| aap_organization.org | data source |
61+
62+
## Inputs
63+
64+
| Name | Description | Type | Default | Required |
65+
|------|-------------|------|---------|:--------:|
66+
| <a name="input_aap_inventory_name"></a> [aap\_inventory\_name](#input\_aap\_inventory\_name) | Name of the AAP inventory to use. | `string` | `"libvirt-infra"` | no |
67+
| <a name="input_aap_job_template_name"></a> [aap\_job\_template\_name](#input\_aap\_job\_template\_name) | Name of the AAP job template to run. If left empty, will default to configure\_<name> | `string` | `""` | no |
68+
| <a name="input_aap_org_name"></a> [aap\_org\_name](#input\_aap\_org\_name) | Name of the Ansible Automation Platform (AAP) organization. | `string` | `"Default"` | no |
69+
| <a name="input_boot_image_url"></a> [boot\_image\_url](#input\_boot\_image\_url) | URL for the base QCOW2 image used as the boot disk. | `string` | `"https://download.fedoraproject.org/pub/fedora/linux/releases/42/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2"` | no |
70+
| <a name="input_bridge_name"></a> [bridge\_name](#input\_bridge\_name) | Name of the network bridge for the second network interface. | `string` | `"nm-bridge"` | no |
71+
| <a name="input_cloudinit_meta_data_template"></a> [cloudinit\_meta\_data\_template](#input\_cloudinit\_meta\_data\_template) | The template content for cloud-init meta-data configuration. | `string` | n/a | yes |
72+
| <a name="input_cloudinit_meta_data_vars"></a> [cloudinit\_meta\_data\_vars](#input\_cloudinit\_meta\_data\_vars) | Variable map for the cloud-init meta-data template. | `map(string)` | n/a | yes |
73+
| <a name="input_cloudinit_network_config_template"></a> [cloudinit\_network\_config\_template](#input\_cloudinit\_network\_config\_template) | The template content for cloud-init network configuration. | `string` | n/a | yes |
74+
| <a name="input_cloudinit_network_config_vars"></a> [cloudinit\_network\_config\_vars](#input\_cloudinit\_network\_config\_vars) | Variable map for the cloud-init network configuration template. | `map(string)` | n/a | yes |
75+
| <a name="input_cloudinit_user_data_template"></a> [cloudinit\_user\_data\_template](#input\_cloudinit\_user\_data\_template) | The template content for cloud-init user-data configuration. | `string` | n/a | yes |
76+
| <a name="input_cloudinit_user_data_vars"></a> [cloudinit\_user\_data\_vars](#input\_cloudinit\_user\_data\_vars) | Variable map for the cloud-init user-data template. Set to {} if not used. | `map(string)` | n/a | yes |
77+
| <a name="input_description"></a> [description](#input\_description) | Description for the libvirt domain (virtual machine). | `string` | `""` | no |
78+
| <a name="input_enable_aap"></a> [enable\_aap](#input\_enable\_aap) | Whether to provision Ansible Automation Platform (AAP) resources for this domain. | `bool` | `false` | no |
79+
| <a name="input_extra_volumes"></a> [extra\_volumes](#input\_extra\_volumes) | List of additional volumes to attach to the domain. Each object should contain:<br/> - name: Name of the volume.<br/> - size: Size of the volume in bytes.<br/>Example:<br/>[<br/> {<br/> name = "runner-var-lib-docker.qcow2"<br/> size = 107374182400<br/> }<br/>] | <pre>list(object({<br/> name = string<br/> size = number<br/> }))</pre> | `[]` | no |
80+
| <a name="input_memory"></a> [memory](#input\_memory) | Amount of memory (in MB) to assign to the domain. | `number` | `2048` | no |
81+
| <a name="input_name"></a> [name](#input\_name) | The name of the libvirt domain (virtual machine) and related resources. | `string` | n/a | yes |
82+
| <a name="input_private_ip_addr"></a> [private\_ip\_addr](#input\_private\_ip\_addr) | Private IP address to assign to the VM (used for network config and inventory). | `string` | n/a | yes |
83+
| <a name="input_proxyhost"></a> [proxyhost](#input\_proxyhost) | Proxy host for SSH connection, used in ansible\_ssh\_common\_args. | `string` | n/a | yes |
84+
| <a name="input_storage_pool"></a> [storage\_pool](#input\_storage\_pool) | Name of the libvirt storage pool where volumes will be created. | `string` | `"default"` | no |
85+
| <a name="input_vcpu"></a> [vcpu](#input\_vcpu) | Number of virtual CPUs to assign to the domain. | `number` | `1` | no |
86+
87+
## Outputs
88+
89+
| Name | Description |
90+
|------|-------------|
91+
| <a name="output_boot_volume_id"></a> [boot\_volume\_id](#output\_boot\_volume\_id) | The ID of the boot volume |
92+
| <a name="output_cloudinit_disk_id"></a> [cloudinit\_disk\_id](#output\_cloudinit\_disk\_id) | The ID of the cloud-init disk |
93+
| <a name="output_domain_id"></a> [domain\_id](#output\_domain\_id) | The ID of the libvirt domain |
94+
| <a name="output_domain_name"></a> [domain\_name](#output\_domain\_name) | The name of the libvirt domain |
95+
<!-- END_TF_DOCS -->

0 commit comments

Comments
 (0)