Infraestrutura KVM usando Terraform e Packer
Um guia passo a passo para implementar uma infraestrutura KVM com Packer e Terraform, automatizando a criação e o provisionamento de VMs.
Parte 1: Instalando o Packer no Ubuntu
O Packer será usado para criar uma imagem base do sistema. Para instalá-lo no Ubuntu, execute os comandos abaixo:
1
2
3
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update && sudo apt-get install packer
Para verificar a instalação, execute:
1
packer -v
Com o Packer instalado, seguimos para a criação dos scripts que definem a imagem do sistema.
Parte 2: Criando os Scripts Packer
Estrutura do Diretório: Organize a estrutura de diretórios criando uma pasta para armazenar os arquivos necessários para o Packer.
1 2
mkdir -p ~/packer/kvm/ol8 cd ~/packer/kvm/ol8
Script de Configuração HCL -
os-install.pkr.hcl: Esse script define as configurações do Packer para criar uma imagem do sistema. Ele utiliza o plugin QEMU para KVM e configura o ISO do Oracle Linux 8.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
packer { required_version = ">= 1.10.0" required_plugins { qemu = { version = "= 1.1.0" source = "github.com/hashicorp/qemu" } } } source "qemu" "iso" { vm_name = "ol8-amd64.raw" iso_url = "https://yum.oracle.com/ISOS/OracleLinux/OL8/u10/x86_64/OracleLinux-R8-U10-x86_64-boot.iso" iso_checksum = "c7009ca2b28ddbedd6c09fc9141f933dec01a6ea73c503634786809746af1906" memory = 2048 disk_image = false output_directory = "build/os-base" accelerator = "kvm" disk_size = "16384M" disk_interface = "virtio" format = "raw" net_device = "virtio-net" boot_wait = "3s" boot_command = [ "<up>", "<tab><wait>", " inst.ks=http://{{.HTTPIP}}:{{.HTTPPort}}/ks.cfg", "<enter>" ] http_directory = "http" cpu_model = "host" shutdown_command = "echo 'packer' | sudo -S shutdown -P now" ssh_username = "packer" ssh_password = "packer" ssh_timeout = "60m" } build { name = "iso" sources = ["source.qemu.iso"] }
Script Kickstart para Automação da Instalação -
http/ks.cfg: Esse arquivo define configurações automáticas para instalação do Oracle Linux. Primeiro, crie a pastahttppara armazenar o script Kickstart.1
mkdir httpDentro de
http/ks.cfg, adicione o conteúdo abaixo:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
graphical %addon com_redhat_kdump --enable --reserve-mb='auto' %end keyboard --xlayouts='br' lang pt_BR.UTF-8 url --url="http://yum.oracle.com/repo/OracleLinux/OL8/baseos/latest/x86_64" %packages @^minimal-environment %end firstboot --enable ignoredisk --only-use=vda autopart clearpart --none --initlabel timezone America/Sao_Paulo --utc rootpw --lock user --groups=wheel --name=packer --password=$6$Jfl.H/kwDSeu7FWF$S/Mc/qsxM2DRupVkxKQawCgjQ3.i6beyCgY1fQCC0NUadW9pucgYnraGMWaCSg8g6t4GbozowE40X/FtAGert. --iscrypted --gecos="packer" reboot %post echo "packer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/01packer /bin/chown root:root /etc/sudoers.d/01packer /bin/chmod 0440 /etc/sudoers.d/01packer yum install -y cloud-init qemu-guest-agent %end
Build da Imagem: Agora, inicialize o Packer e inicie o processo de criação da imagem com os seguintes comandos:
1 2
packer init . PACKER_LOG=1 packer build os-install.pkr.hcl
Conversão da Imagem: Converta a imagem para o formato qcow2, que será utilizado pelo KVM:
1
qemu-img convert -O qcow2 -c build/os-base/ol8-amd64.raw /home/gean/kvm/templates/ol8-amd64.qcow2
Parte 3: Criando os Scripts Terraform
Nesta etapa, usaremos o Terraform para configurar e provisionar uma máquina virtual KVM utilizando a imagem criada pelo Packer. Abaixo estão os passos e scripts necessários.
Estrutura do Diretório: Certifique-se de estar em uma pasta onde deseja armazenar os arquivos Terraform (como
~/terraform/kvm).Script Principal HCL -
main.tf: Este arquivo define os recursos necessários, incluindo o provider libvirt e a configuração da máquina virtual. Vamos criar o arquivomain.tfcom o seguinte conteúdo:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
terraform { required_providers { libvirt = { source = "dmacvicar/libvirt" } } } provider "libvirt" { uri = "qemu:///system" } resource "libvirt_volume" "os_image" { name = "lvm.qcow2" pool = "default" source = "/home/gean/kvm/templates/ol8-amd64.qcow2" format = "qcow2" } data "template_file" "user_data" { template = file("${path.module}/cloud_init.yml") } resource "libvirt_cloudinit_disk" "cloudinit_resized" { name = "cloudinit_resized.iso" user_data = data.template_file.user_data.rendered pool = "default" } resource "libvirt_domain" "lvm" { name = "lvm" memory = "2048" vcpu = 2 cpu { mode = "host-passthrough" } cloudinit = libvirt_cloudinit_disk.cloudinit_resized.id network_interface { network_name = "default" wait_for_lease = true } console { type = "pty" target_port = "0" target_type = "serial" } disk { volume_id = libvirt_volume.os_image.id } graphics { type = "spice" listen_type = "none" } } output "ip" { value = libvirt_domain.lvm.network_interface[0].addresses[0] }
Arquivo YAML de Configuração do Cloud-init -
cloud_init.yml: Este arquivo configura o cloud-init, permitindo inicializar a VM com um usuário configurado e uma chave SSH. Crie o arquivocloud_init.ymlcom o seguinte conteúdo:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#cloud-config users: - name: gean gecos: "Gean Martins" sudo: "ALL=(ALL) NOPASSWD:ALL" shell: /bin/bash lock_passwd: false ssh-authorized-keys: - ${file("~/.ssh/tfvms.pub")} ssh_pwauth: true chpasswd: list: | gean: $6$kp7ay8JwVMNBTlL1$xf/nfw3WWePI3PhzccOTaaNXiDVrhIBck6i4pKJ89897u3/xNbDXc5zf0LInnCN0HkP4A/jVbQVk3qTMt4hq/1 expire: false runcmd: - hostnamectl set-hostname lvm
Parte 4: Executando o Terraform para Provisionar a VM
Agora que temos todos os scripts, vamos rodar o Terraform para criar a VM.
Inicializar o Terraform: Inicialize o diretório para que o Terraform baixe os providers necessários.
1
terraform init
Formatação e Validação dos Arquivos: Formate e valide os arquivos
.tfpara assegurar que estão corretos.1 2
terraform fmt terraform validatePlano de Execução: Gere o plano de execução para visualizar as alterações que o Terraform aplicará.
1
terraform plan
Aplicar Configurações: Aplique as configurações para provisionar a VM.
1
terraform apply
Resultado
Ao final do processo, o Terraform retornará o IP da nova máquina virtual provisionada, disponível na saída output "ip".