terraform { required_version = ">= 0.13" required_providers { libvirt = { source = "dmacvicar/libvirt" version = "~> 0.7.0" } } } # instance the provider provider "libvirt" { uri = "qemu:///system" } resource "libvirt_pool" "debian_basic" { name = "debian_basic" type = "dir" path = "/home/atm/code/libvirt/pool/debian_basic" } resource "libvirt_volume" "debian11-qcow2" { name = "debian11-qcow2" pool = libvirt_pool.debian_basic.name source = "https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-genericcloud-amd64.qcow2" format = "qcow2" } variable "vm_count" { default = 1 } resource "libvirt_volume" "domain_debian_basic_volume" { name = "domain_debian_basic_volume-${count.index}" base_volume_id = libvirt_volume.debian11-qcow2.id count = var.vm_count size = 5368709120 } data "template_file" "user_data" { template = file("${path.module}/cloud_init.cfg") } data "template_file" "network_config" { template = file("${path.module}/network_config.cfg") } resource "libvirt_cloudinit_disk" "commoninit" { name = "commoninit.iso" user_data = data.template_file.user_data.rendered network_config = data.template_file.network_config.rendered pool = libvirt_pool.debian_basic.name } # Create the machine resource "libvirt_domain" "domain_debian_basic" { count = var.vm_count name = "debian_basic_${count.index}" memory = "3000" vcpu = 4 cloudinit = libvirt_cloudinit_disk.commoninit.id network_interface { network_name = "default" wait_for_lease = true } # IMPORTANT: this is a known bug on cloud images, since they expect a console # we need to pass it # https://bugs.launchpad.net/cloud-images/+bug/1573095 console { type = "pty" target_port = "0" target_type = "serial" } console { type = "pty" target_type = "virtio" target_port = "1" } disk { volume_id = element(libvirt_volume.domain_debian_basic_volume.*.id, count.index) } graphics { type = "spice" listen_type = "address" autoport = true } } locals { vm_ips = [for i in libvirt_domain.domain_debian_basic : i.network_interface.0.addresses[0]] vm_names = [for i in libvirt_domain.domain_debian_basic : i.name] vm_map = [for i in libvirt_domain.domain_debian_basic : { ip = i.network_interface.0.addresses[0], name = i.name }] } output "debian_ip" { value = local.vm_map } resource "local_file" "hosts_yml" { content = templatefile("./templates/hosts.yml.tftpl", { vm_ips = local.vm_ips, vm_names = local.vm_names, vms = local.vm_map }) filename = "./ansible/inventory/hosts.ini" }