User Tools

Site Tools


wiki:docker:infra_docker_kvm_tf

Docker - Infraestrutura KVM com Terraform

main.tf
# $ 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
  }
}
debian-cloud-init.yml
# $ 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
debian-network-config.yml
$ 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 
ol9-cloud-init.yml
# $ 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
ol9-network-config.yml
# $ 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
ubuntu-cloud-init.yml
# $ 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
ubuntu-network-config.yml
# $ 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
terraform.tfvars
# $ 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

debian-cloud-init.yml
# $ 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
wiki/docker/infra_docker_kvm_tf.txt · Last modified: by Wiki Administrator