Libvirt (Qemu) Terraform
Create workdir and add files:
- provider.tf
Terraform
# see https://github.com/hashicorp/terraform
terraform {
required_version = ">1.1.3"
required_providers {
# see https://registry.terraform.io/providers/hashicorp/random
random = {
source = "hashicorp/random"
version = "3.1.0"
}
# see https://registry.terraform.io/providers/hashicorp/template
template = {
source = "hashicorp/template"
version = "2.2.0"
}
# see https://registry.terraform.io/providers/dmacvicar/libvirt
# see https://github.com/dmacvicar/terraform-provider-libvirt
libvirt = {
source = "dmacvicar/libvirt"
version = "0.6.11"
}
}
}
provider "libvirt" {
## Configuration options
uri = "qemu:///system"
# uri = "qemu+ssh://[email protected]:42315/system"
}
- libvirt.tf
Terraform
resource "libvirt_volume" "ubuntu-terra" {
name = "ubuntu-terra.qcow2"
pool = "kvm-disks" # List storage pools using virsh pool-list
# source = "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"
source = "./jammy-server-cloudimg-amd64.img" # faster (but you have to download img)
format = "qcow2"
}
# Give a Disk size
resource "libvirt_volume" "ubuntu-terra_resized" {
name = "disk"
base_volume_id = "${libvirt_volume.ubuntu-terra.id}"
pool = "kvm-disks"
size = 30361393152
}
# Use CloudInit ISO to add ssh-key to the instance
resource "libvirt_cloudinit_disk" "commoninit" {
name = "ubuntu-terra-commoninit.iso"
pool = "kvm-disks"
user_data = data.template_file.user_data.rendered
network_config = data.template_file.network_config.rendered
}
# ssh key and users - in cloudinit
data "template_file" "user_data" {
template = file("${path.module}/cloud_init.cfg")
vars = {
hostname = "ubuntu-terra"
fqdn = "ubuntu-terra.urdomain.com"
}
}
data "template_file" "network_config" {
template = file("${path.module}/network_config_dhcp.cfg")
}
# Define KVM domain to create
resource "libvirt_domain" "ubuntu-terra" {
name = "ubuntu-terra"
memory = "2048"
vcpu = 2
network_interface {
network_name = "default" # List networks with virsh net-list
bridge = "virbr0"
addresses = ["192.168.122.200"]
}
disk {
volume_id = "${libvirt_volume.ubuntu-terra_resized.id}"
}
console {
type = "pty"
target_type = "serial"
target_port = "0"
}
graphics {
type = "spice"
listen_type = "address"
autoport = true
}
cloudinit = libvirt_cloudinit_disk.commoninit.id
}
# # Output Server IP
output "ip" {
value = "${libvirt_domain.ubuntu-terra.network_interface.0.addresses.0}"
}
- cloud_init.cfg
INI
#cloud-config
hostname: ubuntu-terra
fqdn: urdomain.com # optional
manage_etc_hosts: true
users:
- name: ubuntu
sudo: ALL=(ALL) NOPASSWD:ALL
groups: users, admin
home: /home/ubuntu
shell: /bin/bash
lock_passwd: false
ssh-authorized-keys:
- ${file("/home/user/.ssh/id_ed25519.pub")} # add your user
# only cert auth via ssh (console access can still login)
ssh_pwauth: false
disable_root: false
chpasswd:
list: |
ubuntu:linux
expire: False
packages:
- qemu-guest-agent
- nano
- cmatrix
- net-tools
- ncdu
- wireguard
- resolvconf
# add packages
# test of writing content
write_files:
- content: |
The quick brown fox jumped
over the lazy dog
path: /root/test.txt
# written to /var/log/cloud-init-output.log
final_message: "The system is finally up, after $UPTIME seconds"
- network.cfg (check what ethernet nic you VM gets and change it)