====== Infraestrutura KVM com Terraform para Docker Swarm ======
Este tutorial explica como configurar uma infraestrutura utilizando KVM com Terraform para provisionar um cluster Docker Swarm. A infraestrutura inclui um manager e dois workers, além de um container para registro de imagens Docker.
===== Requisitos =====
- **KVM** instalado e configurado.
- **Terraform** para orquestração.
- Template de imagem **Ubuntu 22.04 Cloud**.
- Chave SSH pública para autenticação.
===== Arquivos principais =====
==== main.tf ====
Este arquivo define os recursos que serão provisionados no KVM usando o provider Libvirt.
variable "vms" {
type = list(map(any))
}
terraform {
required_providers {
libvirt = {
source = "dmacvicar/libvirt"
}
}
}
provider "libvirt" {
uri = "qemu:///system"
}
resource "libvirt_network" "swarm" {
name = "swarm"
mode = "nat"
addresses = ["10.2.3.0/24"]
autostart = true
dhcp {
enabled = false
}
dns {
enabled = true
}
}
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"
}
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
}
data "template_file" "user_data" {
for_each = { for vm in var.vms : vm.name => vm }
template = file("${path.module}/${each.value["user_data"]}")
vars = {
hostname = each.value["hostname"]
}
}
data "template_file" "network_config" {
for_each = { for vm in var.vms : vm.name => vm }
template = file("${path.module}/${each.value["network_config"]}")
vars = {
network_ip = each.value["network_ip"]
}
}
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"]
}
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
}
}
==== terraform.tfvars ====
Este arquivo define as variáveis usadas para configurar as VMs. Ajuste os valores conforme sua necessidade.
vms = [
{
name = "docker-manager"
cpu = 2
memory = 4096
disksize = 32
storage_pool = "default"
hostname = "docker-manager"
os_image_name = "docker_manager_image.qcow2"
os_datas_name = "docker_manager_datas.qcow2"
network_name = "swarm"
user_data = "cloud-init.yml"
network_config = "network-config.yml"
network_ip = "10.2.3.10"
os_image_url = "/home/gean/kvm/templates/ubuntu-22.04-server-cloudimg-amd64.img"
},
{
name = "docker-worker1"
cpu = 2
memory = 2048
disksize = 32
storage_pool = "default"
hostname = "docker-worker1"
os_image_name = "docker_worker1_image.qcow2"
os_datas_name = "docker_worker1_datas.qcow2"
network_name = "swarm"
user_data = "cloud-init.yml"
network_config = "network-config.yml"
network_ip = "10.2.3.11"
os_image_url = "/home/gean/kvm/templates/ubuntu-22.04-server-cloudimg-amd64.img"
},
{
name = "docker-worker2"
cpu = 2
memory = 2048
disksize = 32
storage_pool = "default"
hostname = "docker-worker2"
os_image_name = "docker_worker2_image.qcow2"
os_datas_name = "docker_worker2_datas.qcow2"
network_name = "swarm"
user_data = "cloud-init.yml"
network_config = "network-config.yml"
network_ip = "10.2.3.12"
os_image_url = "/home/gean/kvm/templates/ubuntu-22.04-server-cloudimg-amd64.img"
},
{
name = "docker-registry"
cpu = 2
memory = 2048
disksize = 32
storage_pool = "default"
hostname = "docker-registry"
os_image_name = "docker_registry_image.qcow2"
os_datas_name = "docker_registry_datas.qcow2"
network_name = "swarm"
user_data = "cloud-init.yml"
network_config = "network-config.yml"
network_ip = "10.2.3.13"
os_image_url = "/home/gean/kvm/templates/ubuntu-22.04-server-cloudimg-amd64.img"
},
]
==== cloud-init.yml ====
Este arquivo define a configuração de inicialização da VM, como hostname, criação de usuários, e instalação de pacotes.
#cloud-config
# Definindo o hostname dinamicamente
hostname: ${hostname}
# Criação de usuário e configuração de SSH
users:
- name: gean
sudo: ALL=(ALL) NOPASSWD:ALL
groups: users, sudo
shell: /bin/bash
ssh_authorized_keys:
- ${file("~/.ssh/tfvms.pub")}
# Definir senha root
chpasswd:
list: |
root:$6$R4tXC5apTx$f4WVAylB/SZ/0ppE7Zp4lurvzAhcm.BaU3xJKaoESu7cv13sR7RYVkjVQwxtvA9/vUggWu/a9N0L9EP1lg/Ez1
expire: False
# Atualização de pacotes e instalação de utilitários
package_update: true
package_upgrade: true
# Lista de pacotes para instalar
packages:
- qemu-guest-agent
- bash-completion
==== network-config.yml ====
Arquivo que define as configurações de rede da VM, como IP e rota de gateway.
#cloud-config
network:
version: 2
ethernets:
ens3:
addresses:
- ${network_ip}/24
nameservers:
addresses:
- 10.2.3.1
routes:
- to: default
via: 10.2.3.1
===== Passos para execução =====
1. **Instale o Terraform e KVM** em sua máquina.
2. Crie um diretório de trabalho e coloque os arquivos `main.tf`, `terraform.tfvars`, `cloud-init.yml` e `network-config.yml` nesse diretório.
3. Execute os comandos a seguir no terminal para iniciar a infraestrutura:
terraform init
terraform fmt
terraform validate
terraform apply
4. O Terraform criará o cluster Docker Swarm com as VMs definidas.
===== Considerações Finais =====
- Ajuste as variáveis no arquivo ''terraform.tfvars'' conforme sua infraestrutura.
- Verifique se o Terraform e o KVM estão corretamente configurados no ambiente.