====== Docker - Infraestrutura KVM com Terraform ====== # $ vim main.tf # Configuração do provider Terraform para o uso de libvirt para provisionamento de VMs terraform { required_providers { libvirt = { source = "dmacvicar/libvirt" } } } # Definição do provider libvirt com a URI do sistema qemu, que é um hypervisor local provider "libvirt" { uri = "qemu:///system" } # Declaração de variável para armazenar a configuração das VMs variable "vms" { description = "A list of virtual machines" type = list(object({ name = string cpu = number memory = number disksize = number docker_vol = number storage_pool = string os_image_name = string os_datas_name = string docker_vol_name = string network_name = string user_data = string network_config = string os_image_url = string })) default = [] } # Configuração de rede virtual no libvirt com NAT, sem DHCP, indicando mais controle sobre a conectividade resource "libvirt_network" "tfnet" { name = "tfnet" mode = "nat" addresses = ["10.1.2.0/24"] autostart = true dhcp { enabled = false } dns { enabled = true local_only = true } } # Criação de volumes para as imagens do sistema operacional de cada VM, usando contagem baseada no número de VMs 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" } # Criação de volumes para os discos de dados de cada VM resource "libvirt_volume" "os_volume" { 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 // GB to bytes } # Criação de volumes para os discos de dados de cada VM resource "libvirt_volume" "docker_vol" { for_each = { for vm in var.vms : vm.name => vm } name = each.value.docker_vol_name pool = each.value.storage_pool size = each.value.docker_vol * 1024 * 1024 * 1024 // GB to bytes } # Geração de configurações de usuário e rede a partir de templates de arquivos de cloud-init data "template_file" "user_data" { for_each = { for vm in var.vms : vm.name => vm } template = file("${path.module}/${each.value.user_data}") } data "template_file" "network_config" { for_each = { for vm in var.vms : vm.name => vm } template = file("${path.module}/${each.value.network_config}") } # Criação de discos de cloud-init para as VMs, contendo as configurações de usuário e rede resource "libvirt_cloudinit_disk" "cloudinit" { for_each = { for vm in var.vms : vm.name => vm } name = "${each.key}_cloudinit.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 } # Definição das domínios das VMs, configurando recursos como memória, CPU e interfaces de rede resource "libvirt_domain" "domain" { for_each = { for vm in var.vms : vm.name => vm } name = each.key memory = each.value.memory vcpu = each.value.cpu cloudinit = libvirt_cloudinit_disk.cloudinit[each.key].id cpu { mode = "host-passthrough" } 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_volume[each.key].id } disk { volume_id = libvirt_volume.docker_vol[each.key].id } graphics { type = "spice" listen_type = "address" autoport = true } } # $ vim debian-cloud-init.yml #cloud-config # Usuários e grupos users: - name: gean sudo: ALL=(ALL) NOPASSWD:ALL groups: sudo,users shell: /bin/bash ssh-authorized-keys: - ${file("~/.ssh/tfvms.pub")} # Desativa a senha para todos os usuários, exceto root disable_root: false ssh_pwauth: false # Configuração da senha do root permitida apenas no console chpasswd: list: | root:root expire: False # Garantir que o acesso por senha esteja desativado para todos, exceto para o console system_info: default_user: lock_passwd: true # Configurações de segurança para SSH sshd_config: PermitRootLogin: prohibit-password PasswordAuthentication: no ChallengeResponseAuthentication: no UsePAM: yes PermitEmptyPasswords: no # Pacotes a serem instalados packages: - qemu-guest-agent - bash-completion # Configurações de atualização de pacotes package_update: true package_upgrade: true ## Set Hostname runcmd: - hostnamectl set-hostname docker-ded $ cat debian-network-config.yml #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 # $ vim ol9-cloud-init.yml #cloud-config # Usuários e grupos users: - name: gean sudo: ALL=(ALL) NOPASSWD:ALL groups: whell,adm,users shell: /bin/bash ssh-authorized-keys: - ${file("~/.ssh/tfvms.pub")} # Desativa a senha para todos os usuários, exceto root disable_root: false ssh_pwauth: false # Configuração da senha do root permitida apenas no console chpasswd: list: | root:root expire: False # Garantir que o acesso por senha esteja desativado para todos, exceto para o console system_info: default_user: lock_passwd: true # Configurações de segurança para SSH sshd_config: PermitRootLogin: prohibit-password PasswordAuthentication: no ChallengeResponseAuthentication: no UsePAM: yes PermitEmptyPasswords: no # Pacotes a serem instalados packages: - qemu-guest-agent - bash-completion # Configurações de atualização de pacotes package_update: true package_upgrade: true ## Set Hostname runcmd: - hostnamectl set-hostname docker-ol # $ vim ol9-network-config.yml #cloud-config network: version: 1 config: - type: physical name: eth0 subnets: - type: static address: 10.1.2.101/24 gateway: 10.1.2.1 # $ vim ubuntu-cloud-init.yml #cloud-config # Usuários e grupos users: - name: gean sudo: ALL=(ALL) NOPASSWD:ALL groups: sudo,adm,users shell: /bin/bash ssh-authorized-keys: - ${file("~/.ssh/tfvms.pub")} # Desativa a senha para todos os usuários, exceto root disable_root: false ssh_pwauth: false # Configuração da senha do root permitida apenas no console chpasswd: list: | root:root expire: False # Garantir que o acesso por senha esteja desativado para todos, exceto para o console system_info: default_user: lock_passwd: true # Configurações de segurança para SSH sshd_config: PermitRootLogin: prohibit-password PasswordAuthentication: no ChallengeResponseAuthentication: no UsePAM: yes PermitEmptyPasswords: no # Pacotes a serem instalados packages: - qemu-guest-agent - bash-completion # Configurações de atualização de pacotes package_update: true package_upgrade: true ## Set Hostname runcmd: - hostnamectl set-hostname docker-ub # $ vim ubuntu-network-config.yml #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 # $ vim terraform.tfvars vms = [ { name = "debian" cpu = 2 memory = 2048 disksize = 32 docker_vol = 32 storage_pool = "default" os_image_name = "debian_image.qcow2" os_datas_name = "debian_datas.qcow2" docker_vol_name = "debian_docker.qcow2" network_name = "tfnet" user_data = "debian-cloud-init.yml" network_config = "debian-network-config.yml" os_image_url = "/home/gean/kvm/templates/debian-12-generic-amd64.qcow2" }, { name = "oracle" cpu = 2 memory = 2048 disksize = 64 docker_vol = 32 storage_pool = "default" os_image_name = "oracle_image.qcow2" os_datas_name = "oracle_datas.qcow2" docker_vol_name = "oracle_docker.qcow2" network_name = "tfnet" user_data = "ol9-cloud-init.yml" network_config = "ol9-network-config.yml" os_image_url = "/home/gean/kvm/templates/OL9U3_x86_64-kvm-b220.qcow2" }, { name = "ubuntu" cpu = 2 memory = 2048 disksize = 32 docker_vol = 32 storage_pool = "default" os_image_name = "ubuntu_image.qcow2" os_datas_name = "ubuntu_datas.qcow2" docker_vol_name = "ubuntu_docker.qcow2" network_name = "tfnet" user_data = "ubuntu-cloud-init.yml" network_config = "ubuntu-network-config.yml" os_image_url = "/home/gean/kvm/templates/ubuntu-22.04-server-cloudimg-amd64.img" }, ] ===== Montando o volume Docker durante a criação da VM ===== # $ vim debian-cloud-init.yml #cloud-config # Usuários e grupos users: - name: gean sudo: ALL=(ALL) NOPASSWD:ALL groups: sudo,users shell: /bin/bash ssh-authorized-keys: - ${file("~/.ssh/tfvms.pub")} # Desativa a senha para todos os usuários, exceto root disable_root: false ssh_pwauth: false # Configuração da senha do root permitida apenas no console chpasswd: list: | root:root expire: False # Garantir que o acesso por senha esteja desativado para todos, exceto para o console system_info: default_user: lock_passwd: true # Configurações de segurança para SSH sshd_config: PermitRootLogin: prohibit-password PasswordAuthentication: no ChallengeResponseAuthentication: no UsePAM: yes PermitEmptyPasswords: no # Pacotes a serem instalados packages: - qemu-guest-agent - bash-completion # Configurações de atualização de pacotes package_update: true package_upgrade: true runcmd: - hostnamectl set-hostname docker-ded - mkdir /var/lib/docker - mkfs.ext4 /dev/vdb - mount /dev/vdb /var/lib/docker - echo "/dev/vdb /var/lib/docker ext4 defaults 0 0" >> /etc/fstab