Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/monolithprojects/terraform-libvirt-vm
Terraform module for KVM/Libvirt Virtual Machine.
https://github.com/monolithprojects/terraform-libvirt-vm
kvm libvirt libvirt-virtual-machine libvirt-vm-terraform module terraform terraform-module virtual-machine vm
Last synced: 2 months ago
JSON representation
Terraform module for KVM/Libvirt Virtual Machine.
- Host: GitHub
- URL: https://github.com/monolithprojects/terraform-libvirt-vm
- Owner: MonolithProjects
- License: mit
- Created: 2020-12-19T21:17:52.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2024-05-01T20:41:26.000Z (8 months ago)
- Last Synced: 2024-05-03T03:13:39.431Z (8 months ago)
- Topics: kvm, libvirt, libvirt-virtual-machine, libvirt-vm-terraform, module, terraform, terraform-module, virtual-machine, vm
- Language: HCL
- Homepage:
- Size: 58.6 KB
- Stars: 38
- Watchers: 4
- Forks: 14
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# Libvirt VM Terraform module
[![GitHub Actions](https://github.com/MonolithProjects/terraform-libvirt-vm/workflows/Lint/badge.svg)](https://github.com/MonolithProjects/terraform-libvirt-vm/actions)
[![License](https://img.shields.io/github/license/MonolithProjects/terraform-libvirt-vm)](https://github.com/MonolithProjects/terraform-libvirt-vm/blob/master/LICENSE)
[![Terraform](https://badgen.net/badge/Terraform%20Registry/yes/blue?icon=terraform)](https://registry.terraform.io/modules/MonolithProjects/vm/libvirt/latest)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.
## What it provides
- creates one or more VMs
- one NIC per domain, connected to the network using the **bridge interface**
- setup network interface using DHCP or static configuration
- cloud_init VM(s) configuration (Ubuntu+Netplan complient)
- optionally add multiple extra disks
- test the ssh connection## Tested on
- Ubuntu 20.04 TLS Cloud Image
- Ubuntu 22.04 TLS Cloud Image## Requirements
| Name | Version |
|------|---------|
| [terraform](#requirement\_terraform) | >= 1.0 |
| [libvirt](#requirement\_libvirt) | >= 0.7.0 |## Modules
No modules.
## Resources
| Name | Type |
|------|------|
| [libvirt_cloudinit_disk.commoninit](https://registry.terraform.io/providers/dmacvicar/libvirt/latest/docs/resources/cloudinit_disk) | resource |
| [libvirt_domain.virt-machine](https://registry.terraform.io/providers/dmacvicar/libvirt/latest/docs/resources/domain) | resource |
| [libvirt_volume.base-volume-qcow2](https://registry.terraform.io/providers/dmacvicar/libvirt/latest/docs/resources/volume) | resource |
| [libvirt_volume.volume-qcow2](https://registry.terraform.io/providers/dmacvicar/libvirt/latest/docs/resources/volume) | resource |## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| [additional\_disk\_ids](#input\_additional\_disk\_ids) | List of volume ids | `list(string)` | `[]` | no |
| [autostart](#input\_autostart) | Autostart the domain | `bool` | `true` | no |
| [base\_pool\_name](#input\_base\_pool\_name) | Name of base OS image | `string` | `null` | no |
| [base\_volume\_name](#input\_base\_volume\_name) | Name of base OS image | `string` | `null` | no |
| [bridge](#input\_bridge) | Bridge interface | `string` | `"virbr0"` | no |
| [cpu\_mode](#input\_cpu\_mode) | CPU mode | `string` | `"host-passthrough"` | no |
| [dhcp](#input\_dhcp) | Use DHCP or Static IP settings | `bool` | `false` | no |
| [graphics](#input\_graphics) | Graphics type (can be '`spice`' or '`vnc`') | `string` | `spice` | no |
| [index\_start](#input\_index\_start) | From where the indexig start | `number` | `1` | no |
| [ip\_address](#input\_ip\_address) | List of IP addresses | `list(string)` |[| no |
"192.168.123.101"
]
| [ip\_gateway](#input\_ip\_gateway) | IP addresses of a gateway | `string` | `"192.168.123.1"` | no |
| [ip\_nameserver](#input\_ip\_nameserver) | IP addresses of a nameserver | `string` | `"192.168.123.1"` | no |
| [local\_admin](#input\_local\_admin) | Admin user without ssh access | `string` | `""` | no |
| [local\_admin\_passwd](#input\_local\_admin\_passwd) | Local admin user password | `string` | `"password_example"` | no |
| [memory](#input\_memory) | RAM in MB | `string` | `"1024"` | no |
| [os\_img\_url](#input\_os\_img\_url) | URL to the OS image | `string` | `"https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"` | no |
| [pool](#input\_pool) | Storage pool name | `string` | `"default"` | no |
| [runcmd](#input\_runcmd) | Extra commands to be run with cloud init | `list(string)` |[| no |
"[ systemctl, daemon-reload ]",
"[ systemctl, enable, qemu-guest-agent ]",
"[ systemctl, start, qemu-guest-agent ]",
"[ systemctl, restart, systemd-networkd ]"
]
| [share\_filesystem](#input\_share\_filesystem) | n/a |object({|
source = string
target = string
readonly = bool
mode = string
}){| no |
"mode": null,
"readonly": false,
"source": null,
"target": null
}
| [ssh\_admin](#input\_ssh\_admin) | Admin user with ssh access | `string` | `"ssh-admin"` | no |
| [ssh\_keys](#input\_ssh\_keys) | List of public ssh keys | `list(string)` | `[]` | no |
| [ssh\_private\_key](#input\_ssh\_private\_key) | Private key for SSH connection test (either path to file or key content) | `string` | `null` | no |
| [system\_volume](#input\_system\_volume) | System Volume size (GB) | `number` | `10` | no |
| [time\_zone](#input\_time\_zone) | Time Zone | `string` | `"UTC"` | no |
| [vcpu](#input\_vcpu) | Number of vCPUs | `number` | `1` | no |
| [vm\_count](#input\_vm\_count) | Number of VMs | `number` | `1` | no |
| [vm\_hostname\_prefix](#input\_vm\_hostname\_prefix) | VM hostname prefix | `string` | `"vm"` | no |
| [xml\_override](#input\_xml\_override) | With these variables you can: Enable hugepages; Set USB controllers; Attach USB devices |object({|
hugepages = bool
usb_controllers = list(object({
model = string
}))
usb_devices = list(object({
vendor = string
product = string
}))
pci_devices_passthrough = list(object({
src_domain = string
src_bus = string
src_slot = string
src_func = string
dst_domain = string
dst_bus = string
dst_slot = string
dst_func = string
}))
}){| no |
"hugepages": false,
"usb_controllers": [
{
"model": "piix3-uhci"
}
],
"usb_devices": []
"pci_devices_passthrough": []
}
| [bastion\_host](#input\_bastion\_host) | ssh bastion host | `string` | `null` | no |
| [bastion\_user](#input\_bastion\_user) | ssh user on bastion host | `string` | `null` | no |
| [bastion\_ssh\_private\_key](#input\_bastion\_ssh\_private\_key) | ssh private key for bastion host (either path to file or key content) | `string` | `null` | no |## Outputs
| Name | Description |
|------|-------------|
| [ip\_address](#output\_ip\_address) | n/a |
| [name](#output\_name) | n/a |## Example
Example with enable HugePages, Attached USB device, changed USB controller model... :
```hcl
terraform {
required_version = ">= 0.13"
required_providers {
libvirt = {
source = "dmacvicar/libvirt"
}
}
}resource "tls_private_key" "ecdsa-p384-bastion" {
algorithm = "ECDSA"
ecdsa_curve = "P384"
}provider "libvirt" {
uri = "qemu+ssh://[email protected]/system"
}module "vm" {
source = "MonolithProjects/vm/libvirt"
version = "1.8.0"vm_hostname_prefix = "server"
vm_count = 3
memory = "2048"
vcpu = 1
pool = "terra_pool"
system_volume = 20
dhcp = true
local_admin = "local-admin"
ssh_admin = "ci-user"
ssh_private_key = "~/.ssh/id_ed25519"
local_admin_passwd = "$6$rounds=4096$xxxxxxxxHASHEDxxxPASSWORD"
ssh_keys = [
"ssh-ed25519 AAAAxxxxxxxxxxxxSSHxxxKEY example",
]
bastion_host = "10.0.0.1"
bastion_user = "admin"
bastion_ssh_private_key = tls_private_key.ecdsa-p384-bastion.private_key_pem
time_zone = "CET"
os_img_url = "file:///home/myuser/ubuntu-20.04-server-cloudimg-amd64.img"
xml_override = {
hugepages = true,
usb_controllers = [
{
model = "qemu-xhci"
}
],
usb_devices = [
{
vendor = "0x0bc2",
product = "0xab28"
}
]
pci_devices_passthrough = [
{
src_domain = "0x0000",
src_bus = "0xc1",
src_slot = "0x00",
src_func = "0x0",
dst_domain = "0x0000",
dst_bus = "0x00",
dst_slot = "0x08"
dst_func = "0x0"
},
{
src_domain = "0x0000",
src_bus = "0xc1",
src_slot = "0x00",
src_func = "0x1",
dst_domain = "0x0000",
dst_bus = "0x00",
dst_slot = "0x09"
dst_func = "0x0"
}
]
}
}output "ip_addresses" {
value = module.nodes
}
```Static IP settings... :
```hcl
terraform {
required_version = ">= 0.13"
required_providers {
libvirt = {
source = "dmacvicar/libvirt"
version = "0.6.3"
}
}
}provider "libvirt" {
uri = "qemu+ssh://[email protected]/system"
}module "vm" {
source = "MonolithProjects/vm/libvirt"
version = "1.8.0"vm_hostname_prefix = "server"
vm_count = 3
memory = "2048"
vcpu = 1
pool = "terra_pool"
system_volume = 20
share_filesystem = {
source = "/tmp"
target = "tmp"
readonly = false
}dhcp = false
ip_address = [
"192.168.165.151",
"192.168.165.152",
"192.168.165.153"
]
ip_gateway = "192.168.165.254"
ip_nameserver = "192.168.165.104"local_admin = "local-admin"
ssh_admin = "ci-user"
ssh_private_key = "~/.ssh/id_ed25519"
local_admin_passwd = "$6$rounds=4096$xxxxxxxxHASHEDxxxPASSWORD"
ssh_keys = [
"ssh-ed25519 AAAAxxxxxxxxxxxxSSHxxxKEY example",
]
time_zone = "CET"
os_img_url = "file:///home/myuser/ubuntu-20.04-server-cloudimg-amd64.img"
}output "outputs" {
value = module.nodes
}
```> The shared directory from the example can be mounted inside the VM with command `sudo mount -t 9p -o trans=virtio,version=9p2000.L,rw tmp /host/tmp`
Create a VM with an extra disk
```
# Creates a 50GB extra-data-disk within vms pool
resource "libvirt_volume" "data_volume" {
pool = "vms"
name = "extra-data-disk.qcow2"
format = "qcow2"
size = 1024*1024*1024*50
}module "vm" {
source = "MonolithProjects/vm/libvirt"
version = "1.8.0"vm_hostname_prefix = "data-server"
base_volume_name = "debian-11-base.qcow2"
base_pool_name = "linked-images"
vm_count = 1
bridge = "bridge-dmz"
memory = "4096"
vcpu = 4
pool = "vms"
system_volume = 25
additional_disk_ids = [ libvirt_volume.data_volume.id ]
dhcp = true
ssh_admin = "admin"
ssh_keys = [
chomp(file("~/.ssh/id_rsa.pub"))
]
time_zone = "America/Argentina/Buenos_Aires"
}output "ip_addresses" {
value = module.vm
}
```## Module output example
```hcl
output_data = {
"ip_address" = [
"192.168.165.151",
"192.168.165.152",
"192.168.165.153",
]
"name" = [
"server01",
"server02",
"server03",
]
}
```## License
MIT
## Author Information
Created in 2020 by Michal Muransky