====== Terraform libvirt - Script para criar uma infra Kubernetes ====== main.tf # Provedor necessário para interagir com o Libvirt terraform { required_providers { libvirt = { source = "dmacvicar/libvirt" } } } # URI para conectar ao Libvirt provider "libvirt" { #uri = "qemu:///system" uri = "qemu+ssh://gean@192.168.0.250/system" } resource "libvirt_network" "kube_net" { name = "kube_net" mode = "nat" addresses = ["10.1.2.0/24"] autostart = true dhcp { enabled = false } } variable "vms" { type = list(object({ name = string # Nome da VM cpu = number # Número de CPUs memory = number # Quantidade de memória (MB) disksize = number # Tamanho do disco (GB) storage_pool = string # Pool de armazenamento os_image_name = string # Nome da imagem do sistema operacional os_datas_name = string # Nome dos dados do sistema operacional network_name = string # Nome da rede user_data = string # Caminho para o arquivo de configuração de inicialização em nuvem network_config = string # Caminho para o arquivo de configuração de rede os_image_url = string # URL da imagem do sistema operacional })) } # Recurso para criar volumes de imagens do sistema operacional resource "libvirt_volume" "os_image" { for_each = { for vm in var.vms : vm.name => vm } name = each.value.os_image_name pool = each.value.storage_pool source = each.value.os_image_url format = "qcow2" } # Recurso para criar volumes de dados do sistema operacional baseados nas imagens resource "libvirt_volume" "os_datas" { for_each = { for vm in var.vms : vm.name => vm } name = each.value.os_datas_name base_volume_id = libvirt_volume.os_image[each.key].id pool = each.value.storage_pool size = each.value.disksize * 1024 * 1024 * 1024 } # Recurso para carregar arquivos de configuração de inicialização em nuvem data "template_file" "user_data" { for_each = { for vm in var.vms : vm.name => vm } template = file(each.value.user_data) } # Recurso para carregar arquivos de configuração de rede data "template_file" "network_config" { for_each = { for vm in var.vms : vm.name => vm } template = file(each.value.network_config) } # Recurso para criar discos de inicialização em nuvem resource "libvirt_cloudinit_disk" "cloudinit" { for_each = { for vm in var.vms : vm.name => vm } name = "cloudinit_${each.key}.iso" user_data = data.template_file.user_data[each.key].rendered network_config = data.template_file.network_config[each.key].rendered pool = each.value.storage_pool } # Recurso para criar as instâncias de máquinas virtuais resource "libvirt_domain" "domain" { for_each = { for vm in var.vms : vm.name => vm } name = each.value.name memory = each.value.memory vcpu = each.value.cpu cpu { mode = "host-passthrough" } cloudinit = libvirt_cloudinit_disk.cloudinit[each.key].id network_interface { network_name = each.value.network_name } console { type = "pty" target_port = "0" target_type = "serial" } console { type = "pty" target_type = "virtio" target_port = "1" } disk { volume_id = libvirt_volume.os_datas[each.key].id } graphics { type = "spice" listen_type = "address" autoport = true } } #cloud-config fqdn: kube-master-01.exemple.com manage_etc_hosts: true ## Modifying root password chpasswd: list: | root:root expire: False ## Enable direct root access disable_root: false ## Allow ssh password authentication ssh_pwauth: true ## Setup users and ssh keys users: - name: gean gecos: Gean Martins groups: users, sudo shell: /bin/bash sudo: ALL=(ALL) NOPASSWD:ALL lock_passwd: true ssh_authorized_keys: - ${file("~/.ssh/id_ed25519.pub")} - name: root ssh_authorized_keys: - ${file("~/.ssh/id_ed25519.pub")} ## Install packages package_update: true package_upgrade: true packages: - qemu-guest-agent - vim - git - python ## Set Hostname runcmd: - hostnamectl set-hostname kube-master-01.exemple.com #cloud-config network: version: 2 ethernets: ens3: addresses: - 10.1.2.100/24 nameservers: addresses: - 10.1.2.1 routes: - to: default via: 10.1.2.1 #cloud-config fqdn: kube-node-01.exemple.com manage_etc_hosts: true ## Modifying root password chpasswd: list: | root:root expire: False ## Enable direct root access disable_root: false ## Allow ssh password authentication ssh_pwauth: true ## Setup users and ssh keys users: - name: gean gecos: Gean Martins groups: users, sudo shell: /bin/bash sudo: ALL=(ALL) NOPASSWD:ALL lock_passwd: true ssh_authorized_keys: - ${file("~/.ssh/id_ed25519.pub")} - name: root ssh_authorized_keys: - ${file("~/.ssh/id_ed25519.pub")} ## Install packages package_update: true package_upgrade: true packages: - qemu-guest-agent - vim - git - python ## Set Hostname runcmd: - hostnamectl set-hostname kube-node-01.exemple.com #cloud-config network: version: 2 ethernets: ens3: addresses: - 10.1.2.101/24 nameservers: addresses: - 10.1.2.1 routes: - to: default via: 10.1.2.1 #cloud-config fqdn: kube-node-02.exemple.com manage_etc_hosts: true ## Modifying root password chpasswd: list: | root:root expire: False ## Enable direct root access disable_root: false ## Allow ssh password authentication ssh_pwauth: true ## Setup users and ssh keys users: - name: gean gecos: Gean Martins groups: users, sudo shell: /bin/bash sudo: ALL=(ALL) NOPASSWD:ALL lock_passwd: true ssh_authorized_keys: - ${file("~/.ssh/id_ed25519.pub")} - name: root ssh_authorized_keys: - ${file("~/.ssh/id_ed25519.pub")} ## Install packages package_update: true package_upgrade: true packages: - qemu-guest-agent - vim - git - python ## Set Hostname runcmd: - hostnamectl set-hostname kube-node-02.exemple.com #cloud-config network: version: 2 ethernets: ens3: addresses: - 10.1.2.102/24 nameservers: addresses: - 10.1.2.1 routes: - to: default via: 10.1.2.1 === Opções para definição de rede === network: ethernets: ens160: addresses: - 10.10.20.6/24 nameservers: addresses: - 10.10.20.71 routes: - to: default via: 10.10.20.1 version: 2 network: ethernets: ens160: addresses: - 10.10.20.6/24 - 2001:678:e20:20::6/64 nameservers: addresses: - 10.10.20.71 routes: - to: default via: 10.10.20.1 - to: default via: 2001:678:e20:20::1 version: 2 # Configurações das máquinas virtuais vms = [ { name = "kube-master-01" cpu = 2 memory = 2048 disksize = 32 storage_pool = "default" os_image_name = "kube_master_01_image.qcow2" os_datas_name = "kube_master_01_datas.qcow2" network_name = "kube_net" ip_address = "10.1.2.100" user_data = "kube-master-cloud-init.yml" network_config = "kube-master-network-config.yml" os_image_url = "/var/lib/libvirt/templates/debian-12-generic-amd64.qcow2" }, { name = "kube-node-01" cpu = 2 memory = 2048 disksize = 32 storage_pool = "default" os_image_name = "kube_01_image.qcow2" os_datas_name = "kube_01_datas.qcow2" network_name = "kube_net" ip_address = "10.1.2.101" user_data = "kube-node-01-cloud-init.yml" network_config = "kube-node-01-network-config.yml" os_image_url = "/var/lib/libvirt/templates/debian-12-generic-amd64.qcow2" }, { name = "kube-node-02" cpu = 2 memory = 2048 disksize = 32 storage_pool = "default" os_image_name = "kube_02_image.qcow2" os_datas_name = "kube_02_datas.qcow2" network_name = "kube_net" ip_address = "10.1.2.102" user_data = "kube-node-02-cloud-init.yml" network_config = "kube-node-02-network-config.yml" os_image_url = "/var/lib/libvirt/templates/debian-12-generic-amd64.qcow2" } ] ===== Referências ===== * [[https://tizutech.com/ubuntu-netplan-gateway4-has-been-deprecated/|Ubuntu netplan gateway4 has been deprecated]] * [[https://github.com/insani4c/terraform-libvirt|terraform-libvirt]] * [[https://github.com/vfricou/terraform_libvirt_examples|terraform_libvirt_examples]] * [[https://github.com/ahpnils/lab-as-code-ng|lab-as-code-ng]] * [[https://github.com/ahpnils/manynodes|manynodes]] * [[https://github.com/fabianlee/terraform-libvirt-ubuntu-examples|terraform-libvirt-ubuntu-examples]]