Skip to content

Commit 4e3c8a0

Browse files
Update
1 parent 7c2938a commit 4e3c8a0

File tree

7 files changed

+96
-28
lines changed

7 files changed

+96
-28
lines changed

README.md

+66-11
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
[![GitHub Actions](https://github.com/MonolithProjects/terraform-libvirt-vm/workflows/Lint/badge.svg)](https://github.com/MonolithProjects/terraform-libvirt-vm/actions)
44
[![License](https://img.shields.io/github/license/MonolithProjects/terraform-libvirt-vm)](https://github.com/MonolithProjects/terraform-libvirt-vm/blob/master/LICENSE)
55

6-
Terraform module for KVM/Libvirt Virtual Machine. This module will create a libvirt domain, storage pool, system volume and configure the VM using cloud_init. This module is using [dmacvicar/libvirt](https://github.com/dmacvicar/terraform-provider-libvirt) Terraform provider.
6+
Terraform module for KVM/Libvirt Virtual Machine. This module will create a KVM Virtual Machine(s), configure it using Cloud Init and test the ssh connection. This module is using [dmacvicar/libvirt](https://github.com/dmacvicar/terraform-provider-libvirt) Terraform provider.
77

88
## What the module provides
99

10-
- create one or more libvirt domains
11-
- create a storage pool
12-
- create a system volume from the pool
13-
- use cloud_init to configure VMs
10+
- create one or more VMs at once
11+
- libvirt domain(s) with one NIC connected to the network using the **bridge interface**
12+
- user can set number of vCPUs, RAM, system volume size
13+
- setup network interface using DHCP or static
14+
- cloud_init VM(s) configuration
15+
- test the ssh connection
1416

1517
## Parameters
1618

@@ -22,22 +24,68 @@ Terraform module for KVM/Libvirt Virtual Machine. This module will create a libv
2224
|vm_hostname_prefix|VM hostname prefix|vm
2325
|memory|RAM in MB|512
2426
|vcpu|Number of vCPUs|1
27+
|pool|Storage pool name|default
2528
|system_volume|System Volume size (GB)|10
2629
|dhcp|Use DHCP or Static IP settings|false
27-
|ip_address|"List of IP addresses|[ "192.168.123.1" ]
28-
|ip_nameserver|IP addresses of a nameserver|192.168.123.1
29-
|ip_gateway|IP addresses of a gateway|192.168.123.1
30+
|ip_address|"List of static IP addresses|[ "192.168.123.1" ]
31+
|ip_nameserver|Static IP addresses of a nameserver|192.168.123.1
32+
|ip_gateway|Static IP addresses of a gateway|192.168.123.1
3033
|ssh_admin|Admin user with ssh access|ssh-admin
3134
|ssh_keys|List of public ssh keys| []
3235
|local_admin|Admin user without ssh access|local-admin
3336
|local_admin_passwd|Local admin user password|password_example
3437
|time_zone|Time Zone|UTC
35-
|ssh_private_key|Private key for SSH connection test|~/.ssh/deployer_keys/id_ed25519
36-
37-
**Cloud_init** configuration can be found in `modules/virt-machine/templates`.
38+
|ssh_private_key|Private key for SSH connection test|~/.ssh/id_ed25519
3839

3940
## Example
4041

42+
DHCP IP settings:
43+
44+
```hcl
45+
terraform {
46+
required_version = ">= 0.13"
47+
required_providers {
48+
libvirt = {
49+
source = "dmacvicar/libvirt"
50+
version = "0.6.3"
51+
}
52+
}
53+
}
54+
55+
provider "libvirt" {
56+
uri = "qemu+ssh://[email protected]/system"
57+
}
58+
59+
module "nodes" {
60+
source = "./modules/virt-machine"
61+
62+
vm_hostname_prefix = "server"
63+
vm_count = 3
64+
memory = "2048"
65+
vcpu = 1
66+
pool = terra_pool
67+
system_volume = 20
68+
69+
dhcp = true
70+
71+
local_admin = "local-admin"
72+
ssh_admin = "ci-user"
73+
ssh_private_key = "~/.ssh/id_ed25519"
74+
local_admin_passwd = "$6$rounds=4096$xxxxxxxxHASHEDxxxPASSWORD"
75+
ssh_keys = [
76+
"ssh-ed25519 AAAAxxxxxxxxxxxxSSHxxxKEY example",
77+
]
78+
time_zone = "CET"
79+
os_img_url = "file:///home/myuser/ubuntu-20.04-server-cloudimg-amd64.img"
80+
}
81+
82+
output "ip_addresses" {
83+
value = module.k3s_nodes
84+
}
85+
```
86+
87+
Static IP settings:
88+
4189
```hcl
4290
terraform {
4391
required_version = ">= 0.13"
@@ -55,11 +103,14 @@ provider "libvirt" {
55103
56104
module "nodes" {
57105
source = "./modules/virt-machine"
106+
58107
vm_hostname_prefix = "server"
59108
vm_count = 3
60109
memory = "2048"
61110
vcpu = 1
111+
pool = terra_pool
62112
system_volume = 20
113+
63114
dhcp = false
64115
ip_address = [
65116
"192.168.165.151",
@@ -68,6 +119,7 @@ module "nodes" {
68119
]
69120
ip_gateway = "192.168.165.254"
70121
ip_nameserver = "192.168.165.104"
122+
71123
local_admin = "local-admin"
72124
ssh_admin = "ci-user"
73125
ssh_private_key = "~/.ssh/id_ed25519"
@@ -79,6 +131,9 @@ module "nodes" {
79131
os_img_url = "file:///home/myuser/ubuntu-20.04-server-cloudimg-amd64.img"
80132
}
81133
134+
output "ip_addresses" {
135+
value = module.k3s_nodes
136+
}
82137
```
83138

84139
## License

modules/virt-machine/main.tf

+6-6
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,19 @@ terraform {
99
}
1010
}
1111

12-
1312
resource "libvirt_domain" "virt-machine" {
1413
count = var.vm_count
1514
name = format("${var.vm_hostname_prefix}%02d", count.index + 1)
1615
memory = var.memory
1716
vcpu = var.vcpu
17+
autostart = true
18+
qemu_agent = true
1819

1920
cloudinit = element(libvirt_cloudinit_disk.commoninit.*.id, count.index)
2021

2122
network_interface {
22-
bridge = "br0"
23-
wait_for_lease = false
23+
bridge = var.bridge
24+
wait_for_lease = true
2425
hostname = format("${var.vm_hostname_prefix}%02d", count.index + 1)
2526
}
2627

@@ -48,15 +49,14 @@ resource "libvirt_domain" "virt-machine" {
4849

4950
provisioner "remote-exec" {
5051
inline = [
51-
"echo \"Virtual Machine is UP!\"",
52-
"uptime",
52+
"echo \"Virtual Machine \"$(hostname)\" is UP!\"",
5353
"date"
5454
]
5555

5656
connection {
5757
type = "ssh"
5858
user = var.ssh_admin
59-
host = var.ip_address[0]
59+
host = self.network_interface.0.addresses.0
6060
private_key = file(var.ssh_private_key)
6161
timeout = "2m"
6262
}

modules/virt-machine/output.tf

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
output "ip_address" {
2+
value = libvirt_domain.virt-machine.*.network_interface.0.addresses.0
3+
}

modules/virt-machine/storage.tf

+3-9
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
1-
resource "libvirt_pool" "terra" {
2-
name = "terratest"
3-
type = "dir"
4-
path = var.libvirt_disk_path
5-
}
6-
71
resource "libvirt_volume" "base-volume-qcow2" {
82
name = format("${var.vm_hostname_prefix}-base.qcow2")
9-
pool = libvirt_pool.terra.name
3+
pool = var.pool
104
source = var.os_img_url
115
format = "qcow2"
126
}
137

148
resource "libvirt_volume" "volume-qcow2" {
159
count = var.vm_count
1610
name = format("${var.vm_hostname_prefix}%02d.qcow2", count.index + 1)
17-
pool = libvirt_pool.terra.name
11+
pool = var.pool
1812
size = 1024*1024*1024*var.system_volume
1913
base_volume_id = libvirt_volume.base-volume-qcow2.id
2014
format = "qcow2"
@@ -25,5 +19,5 @@ resource "libvirt_cloudinit_disk" "commoninit" {
2519
name = format("${var.vm_hostname_prefix}_init%2d.iso", count.index + 1)
2620
user_data = data.template_cloudinit_config.init_config[count.index].rendered
2721
network_config = data.template_file.network_config[count.index].rendered
28-
pool = libvirt_pool.terra.name
22+
pool = var.pool
2923
}

modules/virt-machine/templates/cloud_init.tpl

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@
33
package_upgrade: false
44

55
packages:
6-
- python3
76
- iotop
7+
- python3
8+
- qemu-guest-agent
9+
10+
runcmd:
11+
- [ systemctl, daemon-reload ]
12+
- [ systemctl, enable, qemu-guest-agent ]
13+
- [ systemctl, start, qemu-guest-agent ]
814

915
fqdn: ${hostname}
1016

Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
version: 2
22
ethernets:
33
ens3:
4-
dhcp4: dhcp
4+
dhcp4: true

modules/virt-machine/variables.tf

+10
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ variable "vcpu" {
3535
default = 1
3636
}
3737

38+
variable "pool" {
39+
description = "Storage pool name"
40+
default = "default"
41+
}
42+
3843
variable "system_volume" {
3944
description = "System Volume size (GB)"
4045
default = 10
@@ -46,6 +51,11 @@ variable "dhcp" {
4651
default = false
4752
}
4853

54+
variable "bridge" {
55+
description = "Bridge interface"
56+
default = "br0"
57+
}
58+
4959
variable "ip_address" {
5060
description = "List of IP addresses"
5161
type = list(string)

0 commit comments

Comments
 (0)