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" "centos_basic" { name = "centos_basic" type = "dir" path = "/home/atm/code/libvirt/pool/centos_basic" } # We fetch the latest centos_basic release image from their mirrors resource "libvirt_volume" "centos8-qcow2" { name = "centos8-qcow2" pool = libvirt_pool.centos_basic.name source = "/home/atm/disk-images/CentOS-8-ec2-8.4.2105-20210603.0.x86_64.qcow2" format = "qcow2" } variable "master_count" { default = 1 } variable "follower_count" { default = 2 } resource "libvirt_volume" "domain_centos_master_volume" { name = "domain_centos_master_volume-${count.index}" base_volume_id = libvirt_volume.centos8-qcow2.id count = var.master_count pool = libvirt_pool.centos_basic.name size = 85368709120 } resource "libvirt_volume" "domain_centos_follower_volume" { name = "domain_centos_follower_volume-${count.index}" base_volume_id = libvirt_volume.centos8-qcow2.id pool = libvirt_pool.centos_basic.name count = var.follower_count size = 85368709120 } data "template_file" "user_data" { template = file("${path.module}/cloud_init.cfg") } data "template_file" "network_config" { template = file("${path.module}/network_config.cfg") } # for more info about paramater check this out # https://github.com/dmacvicar/terraform-provider-libvirt/blob/master/website/docs/r/cloudinit.html.markdown # Use CloudInit to add our ssh-key to the instance # you can add also meta_data field 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.centos_basic.name } # Create the follower machine resource "libvirt_domain" "domain_centos_follower" { count = var.follower_count name = "centos_follower_${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_centos_follower_volume.*.id, count.index) } graphics { type = "spice" listen_type = "address" autoport = true } } # Create the machine resource "libvirt_domain" "domain_centos_master" { count = var.master_count name = "centos_master_${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_centos_master_volume.*.id, count.index) } graphics { type = "spice" listen_type = "address" autoport = true } } locals { follower_vm_ips = [for i in libvirt_domain.domain_centos_follower : i.network_interface.0.addresses[0]] follower_vm_names = [for i in libvirt_domain.domain_centos_follower : i.name] # vm_names = zipmap(vm_names, vm_ips) follower_vm_map = [for i in libvirt_domain.domain_centos_follower : { ip = i.network_interface.0.addresses[0], name = i.name }] master_vm_ips = [for i in libvirt_domain.domain_centos_master : i.network_interface.0.addresses[0]] master_vm_names = [for i in libvirt_domain.domain_centos_master : i.name] # vm_names = zipmap(vm_names, vm_ips) master_vm_map = [for i in libvirt_domain.domain_centos_master : { ip = i.network_interface.0.addresses[0], name = i.name }] # libvirt_domain.domain_centos_basic.*.network_interface.0.addresses[0] } output "centos_follower_ip" { #value = [local.vm_ips, local.vm_names] value = local.follower_vm_map } output "centos_master_ip" { #value = [local.vm_ips, local.vm_names] value = local.master_vm_map } resource "local_file" "hosts_yml" { # content = <<-EOT #[debain_basic_webservers]: # hosts: # %{ for vm in libvirt_domain.domain_centos_basic ~} # ${vm.name}: # ansible_host: ${vm.network_interface.0.addresses[0]} # ansible_user: root # %{ endfor ~} # EOT content = templatefile("./templates/hosts.yml.tftpl", { follower_vm_ips = local.follower_vm_ips, follower_vm_names = local.follower_vm_names, follower_vms = local.follower_vm_map, master_vm_ips = local.master_vm_ips, master_vm_names = local.master_vm_names, master_vms = local.master_vm_map }) filename = "./ansible/inventory/hosts.ini" }