Skip to content

Commit 8eb2066

Browse files
Merge pull request #13 from MonolithProjects/develop
New features
2 parents ad6c5ae + cdd4b65 commit 8eb2066

8 files changed

+226
-114
lines changed

Diff for: .pre-commit-config.yaml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
repos:
2+
- repo: https://github.com/pre-commit/pre-commit-hooks
3+
rev: v3.4.0
4+
hooks:
5+
- id: trailing-whitespace
6+
- id: check-merge-conflict
7+
- id: detect-aws-credentials
8+
args: ['--allow-missing-credentials']
9+
- id: detect-private-key
10+
- id: end-of-file-fixer
11+
12+
- repo: https://github.com/antonbabenko/pre-commit-terraform
13+
rev: v1.64.0
14+
hooks:
15+
- id: terraform_fmt
16+
- id: terraform_tflint
17+
- id: terraform_docs
18+
args:
19+
- '--args=--hide providers --sort-by required'

Diff for: README.md

+84-47
Original file line numberDiff line numberDiff line change
@@ -19,42 +19,72 @@ Terraform module for KVM/Libvirt Virtual Machine. This module will create a KVM
1919

2020
- Ubuntu 20.04 TLS
2121

22-
## Parameters
23-
24-
| Parameter | Description | Default value
25-
|-----------------|-----|-----
26-
|os_img_url|URL to the OS image|https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img
27-
|base_pool_name|When defined it will be used in combination with `base_volume_name` to create root volume as linked clone from this pool name|null
28-
|base_volume_name|When defined it will be used in combination with `base_pool_name` to create root volume as linked clone from this pool/vol name. Defining this variable will disable downloading `os_img_url` and creating a base volume| null
29-
|autostart| Autostart the Domain| true
30-
|vm_count|Number of VMs| 1
31-
|index_start|From where the index start| 1
32-
|vm_hostname_prefix|VM hostname prefix|vm
33-
|memory|RAM in MB|1024
34-
|additional_disk_ids|List of volume ids to be attached to domain| []
35-
|hugepages|Use Hugepages|false
36-
|vcpu|Number of vCPUs|1
37-
|pool|Storage pool name|default
38-
|system_volume|System Volume size (GB)|10
39-
|share_filesystem.source|Directory of the host to be shared with the VM|null
40-
|share_filesystem.target|Tag that is exported to the VM as a hint for where to mount the source|null
41-
|share_filesystem.readonly|Enables exporting filesystem as a readonly mount|false
42-
|share_filesystem.mode|Access mode (mapped, passtrough, squash)|null
43-
|bridge|Bridge interface| "virbr0"
44-
|dhcp|Use DHCP or Static IP settings|false
45-
|ip_address|"List of static IP addresses|[ "192.168.123.101" ]
46-
|ip_nameserver|Static IP addresses of a nameserver|192.168.123.1
47-
|ip_gateway|Static IP addresses of a gateway|192.168.123.1
48-
|ssh_admin|Admin user with ssh access|ssh-admin
49-
|ssh_keys|List of public ssh keys| []
50-
|local_admin|Admin user without ssh access|""
51-
|local_admin_passwd|Local admin user password|password_example
52-
|time_zone|Time Zone|UTC
53-
|ssh_private_key|Private key for SSH connection test|null
22+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
23+
## Requirements
24+
25+
| Name | Version |
26+
|------|---------|
27+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13 |
28+
| <a name="requirement_libvirt"></a> [libvirt](#requirement\_libvirt) | >=0.6.9 |
29+
30+
## Modules
31+
32+
No modules.
33+
34+
## Resources
35+
36+
| Name | Type |
37+
|------|------|
38+
| [libvirt_cloudinit_disk.commoninit](https://registry.terraform.io/providers/dmacvicar/libvirt/latest/docs/resources/cloudinit_disk) | resource |
39+
| [libvirt_domain.virt-machine](https://registry.terraform.io/providers/dmacvicar/libvirt/latest/docs/resources/domain) | resource |
40+
| [libvirt_volume.base-volume-qcow2](https://registry.terraform.io/providers/dmacvicar/libvirt/latest/docs/resources/volume) | resource |
41+
| [libvirt_volume.volume-qcow2](https://registry.terraform.io/providers/dmacvicar/libvirt/latest/docs/resources/volume) | resource |
42+
| [template_cloudinit_config.init_config](https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/cloudinit_config) | data source |
43+
| [template_file.init_config](https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/file) | data source |
44+
| [template_file.network_config](https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/file) | data source |
45+
46+
## Inputs
47+
48+
| Name | Description | Type | Default | Required |
49+
|------|-------------|------|---------|:--------:|
50+
| <a name="input_autostart"></a> [autostart](#input\_autostart) | Autostart the domain | `bool` | `true` | no |
51+
| <a name="input_base_pool_name"></a> [base\_pool\_name](#input\_base\_pool\_name) | Name of base OS image | `any` | `null` | no |
52+
| <a name="input_base_volume_name"></a> [base\_volume\_name](#input\_base\_volume\_name) | Name of base OS image | `any` | `null` | no |
53+
| <a name="input_bridge"></a> [bridge](#input\_bridge) | Bridge interface | `string` | `"virbr0"` | no |
54+
| <a name="input_cpu_mode"></a> [cpu\_mode](#input\_cpu\_mode) | CPU mode | `string` | `"host-passthrough"` | no |
55+
| <a name="input_dhcp"></a> [dhcp](#input\_dhcp) | Use DHCP or Static IP settings | `bool` | `false` | no |
56+
| <a name="input_hostname"></a> [hostname](#input\_hostname) | VM hostname or FQDN | `string` | `"server"` | no |
57+
| <a name="input_index_start"></a> [index\_start](#input\_index\_start) | From where the indexig start | `number` | `1` | no |
58+
| <a name="input_ip_address"></a> [ip\_address](#input\_ip\_address) | List of IP addresses | `list(string)` | <pre>[<br> "192.168.123.101"<br>]</pre> | no |
59+
| <a name="input_ip_gateway"></a> [ip\_gateway](#input\_ip\_gateway) | IP addresses of a gateway | `string` | `"192.168.123.1"` | no |
60+
| <a name="input_ip_nameserver"></a> [ip\_nameserver](#input\_ip\_nameserver) | IP addresses of a nameserver | `string` | `"192.168.123.1"` | no |
61+
| <a name="input_local_admin"></a> [local\_admin](#input\_local\_admin) | Admin user without ssh access | `string` | `""` | no |
62+
| <a name="input_local_admin_passwd"></a> [local\_admin\_passwd](#input\_local\_admin\_passwd) | Local admin user password | `string` | `"password_example"` | no |
63+
| <a name="input_memory"></a> [memory](#input\_memory) | RAM in MB | `string` | `"1024"` | no |
64+
| <a name="input_os_img_url"></a> [os\_img\_url](#input\_os\_img\_url) | URL to the OS image | `string` | `"https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img"` | no |
65+
| <a name="input_pool"></a> [pool](#input\_pool) | Storage pool name | `string` | `"default"` | no |
66+
| <a name="input_share_filesystem"></a> [share\_filesystem](#input\_share\_filesystem) | n/a | <pre>object({<br> source = string<br> target = string<br> readonly = bool<br> mode = string<br> })</pre> | <pre>{<br> "mode": null,<br> "readonly": false,<br> "source": null,<br> "target": null<br>}</pre> | no |
67+
| <a name="input_ssh_admin"></a> [ssh\_admin](#input\_ssh\_admin) | Admin user with ssh access | `string` | `"ssh-admin"` | no |
68+
| <a name="input_ssh_keys"></a> [ssh\_keys](#input\_ssh\_keys) | List of public ssh keys | `list(string)` | `[]` | no |
69+
| <a name="input_ssh_private_key"></a> [ssh\_private\_key](#input\_ssh\_private\_key) | Private key for SSH connection test | `any` | `null` | no |
70+
| <a name="input_system_volume"></a> [system\_volume](#input\_system\_volume) | System Volume size (GB) | `number` | `10` | no |
71+
| <a name="input_time_zone"></a> [time\_zone](#input\_time\_zone) | Time Zone | `string` | `"UTC"` | no |
72+
| <a name="input_vcpu"></a> [vcpu](#input\_vcpu) | Number of vCPUs | `number` | `1` | no |
73+
| <a name="input_vm_count"></a> [vm\_count](#input\_vm\_count) | Number of VMs | `number` | `1` | no |
74+
| <a name="input_vm_hostname_prefix"></a> [vm\_hostname\_prefix](#input\_vm\_hostname\_prefix) | VM hostname prefix | `string` | `"vm"` | no |
75+
| <a name="input_xml_override"></a> [xml\_override](#input\_xml\_override) | With these variables you can: Enable hugepages; Set USB controllers; Attach USB devices | `any` | <pre>{<br> "hugepages": false,<br> "usb_controllers": [<br> {<br> "model": "piix3-uhci"<br> }<br> ],<br> "usb_devices": []<br>}</pre> | no |
76+
77+
## Outputs
78+
79+
| Name | Description |
80+
|------|-------------|
81+
| <a name="output_ip_address"></a> [ip\_address](#output\_ip\_address) | n/a |
82+
| <a name="output_name"></a> [name](#output\_name) | n/a |
83+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
5484

5585
## Example
5686

57-
DHCP IP settings:
87+
Example with enable HugePages, Attached USB device, changed USB controller model... :
5888

5989
```hcl
6090
terraform {
@@ -77,30 +107,41 @@ module "vm" {
77107
vm_hostname_prefix = "server"
78108
vm_count = 3
79109
memory = "2048"
80-
hugepages = false
81110
vcpu = 1
82111
pool = "terra_pool"
83112
system_volume = 20
84-
85113
dhcp = true
86-
87114
local_admin = "local-admin"
88115
ssh_admin = "ci-user"
89116
ssh_private_key = "~/.ssh/id_ed25519"
90117
local_admin_passwd = "$6$rounds=4096$xxxxxxxxHASHEDxxxPASSWORD"
91-
ssh_keys = [
92-
"ssh-ed25519 AAAAxxxxxxxxxxxxSSHxxxKEY example",
118+
ssh_keys = [
119+
"ssh-ed25519 AAAAxxxxxxxxxxxxSSHxxxKEY example",
93120
]
94121
time_zone = "CET"
95122
os_img_url = "file:///home/myuser/ubuntu-20.04-server-cloudimg-amd64.img"
123+
xml_override = {
124+
hugepages = true,
125+
usb_controllers = [
126+
{
127+
model = "qemu-xhci"
128+
}
129+
],
130+
usb_devices = [
131+
{
132+
vendor = "0x0bc2",
133+
product = "0xab28"
134+
}
135+
]
136+
}
96137
}
97138
98139
output "ip_addresses" {
99140
value = module.nodes
100141
}
101142
```
102143

103-
Static IP settings and Hugepages:
144+
Static IP settings... :
104145

105146
```hcl
106147
terraform {
@@ -124,7 +165,6 @@ module "vm" {
124165
vm_hostname_prefix = "server"
125166
vm_count = 3
126167
memory = "2048"
127-
hugepages = true
128168
vcpu = 1
129169
pool = "terra_pool"
130170
system_volume = 20
@@ -135,10 +175,10 @@ module "vm" {
135175
}
136176
137177
dhcp = false
138-
ip_address = [
178+
ip_address = [
139179
"192.168.165.151",
140180
"192.168.165.152",
141-
"192.168.165.153"
181+
"192.168.165.153"
142182
]
143183
ip_gateway = "192.168.165.254"
144184
ip_nameserver = "192.168.165.104"
@@ -147,8 +187,8 @@ module "vm" {
147187
ssh_admin = "ci-user"
148188
ssh_private_key = "~/.ssh/id_ed25519"
149189
local_admin_passwd = "$6$rounds=4096$xxxxxxxxHASHEDxxxPASSWORD"
150-
ssh_keys = [
151-
"ssh-ed25519 AAAAxxxxxxxxxxxxSSHxxxKEY example",
190+
ssh_keys = [
191+
"ssh-ed25519 AAAAxxxxxxxxxxxxSSHxxxKEY example",
152192
]
153193
time_zone = "CET"
154194
os_img_url = "file:///home/myuser/ubuntu-20.04-server-cloudimg-amd64.img"
@@ -182,14 +222,11 @@ module "vm" {
182222
vm_count = 1
183223
bridge = "bridge-dmz"
184224
memory = "4096"
185-
hugepages = false
186225
vcpu = 4
187226
pool = "vms"
188227
system_volume = 25
189228
additional_disk_ids = [ libvirt_volume.data_volume.id ]
190-
191229
dhcp = true
192-
193230
ssh_admin = "admin"
194231
ssh_keys = [
195232
chomp(file("~/.ssh/id_rsa.pub"))

Diff for: cloud_init.tf

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
11
data "template_file" "network_config" {
2-
count = var.vm_count
2+
count = var.vm_count
33
template = file("${path.module}/templates/network_config_${var.dhcp == true ? "dhcp" : "static"}.tpl")
44
vars = {
5-
ip_address = element(var.ip_address, count.index)
6-
ip_gateway = var.ip_gateway
5+
ip_address = element(var.ip_address, count.index)
6+
ip_gateway = var.ip_gateway
77
ip_nameserver = var.ip_nameserver
8-
nic = (var.share_filesystem.source == null ? "ens3" : "ens4")
8+
nic = (var.share_filesystem.source == null ? "ens3" : "ens4")
99
# WA: If the shared filesystem is used, Libvirt connects Unclassified device to the 3rd position of PCI bus
1010
}
1111
}
1212

1313
data "template_file" "init_config" {
14-
count = var.vm_count
14+
count = var.vm_count
1515
template = file("${path.module}/templates/cloud_init.tpl")
1616
vars = {
17-
ssh_admin = var.ssh_admin
18-
ssh_keys = local.all_keys
19-
local_admin = var.local_admin
17+
ssh_admin = var.ssh_admin
18+
ssh_keys = local.all_keys
19+
local_admin = var.local_admin
2020
local_admin_passwd = var.local_admin_passwd
21-
hostname = format("${var.vm_hostname_prefix}%02d", count.index + var.index_start)
22-
time_zone = var.time_zone
21+
hostname = format("${var.vm_hostname_prefix}%02d", count.index + var.index_start)
22+
time_zone = var.time_zone
2323
}
2424
}
2525

2626
locals {
2727
all_keys = <<EOT
2828
[
29-
%{~ for keys in var.ssh_keys ~}
29+
%{~for keys in var.ssh_keys~}
3030
"${keys}",
31-
%{~ endfor ~}
31+
%{~endfor~}
3232
]
3333
EOT
3434
}
@@ -43,4 +43,4 @@ data "template_cloudinit_config" "init_config" {
4343
content_type = "text/cloud-config"
4444
content = data.template_file.init_config[count.index].rendered
4545
}
46-
}
46+
}

Diff for: main.tf

+17-14
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11

22
terraform {
33
required_version = ">= 0.13"
4-
required_providers {
5-
libvirt = {
6-
source = "dmacvicar/libvirt"
7-
version = ">=0.6.9"
8-
}
4+
required_providers {
5+
libvirt = {
6+
source = "dmacvicar/libvirt"
7+
version = ">=0.6.9"
98
}
9+
}
1010
}
1111

1212
resource "libvirt_domain" "virt-machine" {
1313
count = var.vm_count
1414
name = format("${var.vm_hostname_prefix}%02d", count.index + var.index_start)
1515
memory = var.memory
16-
vcpu = var.vcpu
16+
cpu {
17+
mode = var.cpu_mode
18+
}
19+
vcpu = var.vcpu
1720
autostart = var.autostart
1821
qemu_agent = true
19-
22+
2023
cloudinit = element(libvirt_cloudinit_disk.commoninit.*.id, count.index)
2124

2225
network_interface {
@@ -26,7 +29,7 @@ resource "libvirt_domain" "virt-machine" {
2629
}
2730

2831
xml {
29-
xslt = (var.hugepages == true ? file("${path.module}/xslt/hugepages.xsl") : null)
32+
xslt = templatefile("${path.module}/xslt/template.tftpl", var.xml_override)
3033
}
3134

3235
console {
@@ -53,7 +56,7 @@ resource "libvirt_domain" "virt-machine" {
5356
}
5457

5558
dynamic "filesystem" {
56-
for_each = var.share_filesystem.source != null ? [ var.share_filesystem.source] : []
59+
for_each = var.share_filesystem.source != null ? [var.share_filesystem.source] : []
5760
content {
5861
source = var.share_filesystem.source
5962
target = var.share_filesystem.target
@@ -74,11 +77,11 @@ resource "libvirt_domain" "virt-machine" {
7477
"date"
7578
]
7679
connection {
77-
type = "ssh"
78-
user = var.ssh_admin
79-
host = self.network_interface.0.addresses.0
80-
private_key = var.ssh_private_key != null ? file(var.ssh_private_key): null
81-
timeout = "2m"
80+
type = "ssh"
81+
user = var.ssh_admin
82+
host = self.network_interface.0.addresses.0
83+
private_key = var.ssh_private_key != null ? file(var.ssh_private_key) : null
84+
timeout = "2m"
8285
}
8386
}
8487
}

Diff for: storage.tf

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
resource "libvirt_volume" "base-volume-qcow2" {
2-
count = var.base_volume_name != null ? 0 : 1
2+
count = var.base_volume_name != null ? 0 : 1
33
name = format("${var.vm_hostname_prefix}-base.qcow2")
44
pool = var.pool
55
source = var.os_img_url
66
format = "qcow2"
77
}
88

99
resource "libvirt_volume" "volume-qcow2" {
10-
count = var.vm_count
11-
name = format("${var.vm_hostname_prefix}%02d.qcow2", count.index + var.index_start)
12-
pool = var.pool
13-
size = 1024*1024*1024*var.system_volume
14-
base_volume_id = var.base_volume_name != null ? null : element(libvirt_volume.base-volume-qcow2, 0).id
10+
count = var.vm_count
11+
name = format("${var.vm_hostname_prefix}%02d.qcow2", count.index + var.index_start)
12+
pool = var.pool
13+
size = 1024 * 1024 * 1024 * var.system_volume
14+
base_volume_id = var.base_volume_name != null ? null : element(libvirt_volume.base-volume-qcow2, 0).id
1515
base_volume_name = var.base_volume_name
1616
base_volume_pool = var.base_pool_name
1717

0 commit comments

Comments
 (0)