Automating KVM infrastructure deployment with terraform-libvirt library

Hi All,

I’m trying to automate deployment of guest machines on KVM. Tried other open-source solutions, but terraform is the one I really like. I’ve used couple of other online resources to put together what I have now ( At the moment I can create n-number of vms as defined in the variables. I’m facing few issues:

  1. All VMs created with this script get the correct name when listed in virsh command, however they all have the same hostname (ubuntu) once I ssh into it - I’d like to have a line in my script to change it, but I’m still struggling to find a way. I’ve tried to populate it with user_data as I read it’s most elegant solution.
    This didn’t do it
    user_data = “${data.template_file.user_data.rendered[count.index]}”

  2. Perhaps stupid question, but I’d like to feed data (hostnames for instance) from external source (csv for instance or a project saved at GitLAB)

  3. I’d like to understand how can I push more cloud-init values

Does anyone have an idea on how this can be solved please?
Thank you for any help!

This is my (working) code now:

instance the provider

provider “libvirt” {
uri = “qemu:///system”

variable “vm_machines” {
description = “Create machines with these names”
type = list(string)
default = [“master01”, “worker01”, “worker02”, “worker03”]

We fetch the latest ubuntu release image from their mirrors

resource “libvirt_volume” “ubuntu” {
name = “${var.vm_machines[count.index]}.qcow2”
count = length(var.vm_machines)
pool = “guest_images”
source = “
format = “qcow2”

Create a network for our VMs

resource “libvirt_network” “vm_network” {
name = “vm_network”
addresses = [“”]
dhcp {
enabled = true

Use CloudInit to add our ssh-key to the instance

resource “libvirt_cloudinit_disk” “commoninit” {
name = “commoninit.iso”
pool = “guest_images”
user_data = “{data.template_file.user_data.rendered}" network_config = "{data.template_file.network_config.rendered}”

data “template_file” “user_data” {
template = “{file("{path.module}/cloud_init.cfg”)}"

data “template_file” “network_config” {
template = “{file("{path.module}/network_config.cfg”)}"

Create the machine

resource “libvirt_domain” “ubuntu” {
count = length(var.vm_machines)
name = var.vm_machines[count.index]
memory = “8196”
vcpu = 2

cloudinit = “${}”

network_interface {
network_id = “${}”
network_name = “vm_network”


Ubuntu can hang is a isa-serial is not present at boot time.

If you find your CPU 100% and never is available this is why

console {
type = “pty”
target_port = “0”
target_type = “serial”

console {
type = “pty”
target_type = “virtio”
target_port = “1”

disk {
volume_id = libvirt_volume.ubuntu[count.index].id
graphics {
type = “vnc”
listen_type = “address”
autoport = “true”