Skip to content

Instantly share code, notes, and snippets.

@idkrn123
Created October 8, 2023 21:36
Show Gist options
  • Save idkrn123/bf8a15fafacf6220731192985683d32b to your computer and use it in GitHub Desktop.
Save idkrn123/bf8a15fafacf6220731192985683d32b to your computer and use it in GitHub Desktop.
terraform libvirt pci passthrough provisioning + simple python utility
variable "instance_name" {}
variable "image_path" {}
variable "libvirt_uri" {}
variable "pci_devices" {
type = list(string)
default = []
}
provider "libvirt" {
uri = var.libvirt_uri
}
resource "libvirt_domain" "domain" {
name = var.instance_name
memory = "1024"
disk {
volume_id = libvirt_volume.volume.id
}
dynamic "host_device" {
for_each = var.pci_devices
content {
source = host_device.value
}
}
}
resource "libvirt_volume" "volume" {
name = "${var.instance_name}_volume"
pool = "default"
source = var.image_path
format = "qcow2"
}
import click
import os
import subprocess
import logging
@click.group()
def cli():
pass
@click.command()
@click.option('--instance-name', prompt=True, help='The name of the instance.')
@click.option('--image-path', default='/var/lib/libvirt/images/', help='The path to the image directory.')
@click.option('--disk-size', prompt=True, help='The size of the disk in GB. If 0, no disk will be created.')
@click.option('--tf-path', prompt=True, help='The path to the Terraform script.')
@click.option('--libvirt-uri', envvar='LIBVIRT_URI', default='qemu:///system', help='The libvirt URI.')
@click.option('--pci-devices', help='Comma-separated list of PCI devices to pass through to the guest.')
def provision(instance_name, image_path, disk_size, tf_path, libvirt_uri, pci_devices):
"""Provision a VM instance using Terraform and libvirt."""
# Set environment variables for Terraform
os.environ['TF_VAR_instance_name'] = instance_name
os.environ['TF_VAR_image_path'] = image_path + instance_name + '.qcow2'
os.environ['TF_VAR_libvirt_uri'] = libvirt_uri
os.environ['TF_VAR_pci_devices'] = pci_devices.split(',') if pci_devices else []
# Create disk image if disk size is not 0
if disk_size != '0':
try:
subprocess.run(['qemu-img', 'create', '-f', 'qcow2', os.environ['TF_VAR_image_path'], disk_size + 'G'], check=True)
except subprocess.CalledProcessError as e:
logging.error(f'qemu-img command failed with exit code {e.returncode}')
return
# Call Terraform script
try:
subprocess.run(['terraform', 'init', tf_path], check=True)
subprocess.run(['terraform', 'apply', '-auto-approve', tf_path], check=True)
except subprocess.CalledProcessError as e:
logging.error(f'Terraform command failed with exit code {e.returncode}')
return
cli.add_command(provision)
if __name__ == '__main__':
cli()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment