#17 DevOps. Как развернуть виртуальные машины в Proxmox с помощью Terraform

Мы уже рассматривали простой запуск виртуалок с помощью Terraform на мощностях Yandex Cloud. А что если нужно сделать это локально, например на Proxmox? Давайте попробуем

Хостовая машина с Terraform — Fedora 40
Proxmox — 8.2.2
Terraform — 1.8.5
Terraform provider plugin for Proxmox — 3.0.1-rc1

С установкой Terraform думаю сложностей не возникнет, платформы у всех разные, просто скину ссылочку на всякий случай

https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli

Далее, для запуска нам понадобится Terraform provider plugin for Proxmox

https://github.com/Telmate/terraform-provider-proxmox

Если Go не установлен

https://go.dev/doc/install

Сторонние плагины можно установить на Linux в ~/.terraform.d/plugins и на Windows в %APPDATA%\terraform.d\plugins

Далее по инструкции подготовим плагин к работе

На машине с Terraform выполняем

git clone https://github.com/Telmate/terraform-provider-proxmox

cd terraform-provider-proxmox

make

PLUGIN_ARCH=linux_amd64

mkdir -p ~/.terraform.d/plugins/registry.example.com/telmate/proxmox/1.0.0/${PLUGIN_ARCH}

cp bin/terraform-provider-proxmox ~/.terraform.d/plugins/registry.example.com/telmate/proxmox/1.0.0/${PLUGIN_ARCH}/

ls -al ~/.terraform.d/plugins/registry.example.com/telmate/proxmox/1.0.0/${PLUGIN_ARCH}/

Смотрите на репозиторий плагина, в зависимости от версии Terraform и вашей ОС, установка может немного отличаться

Далее подготовим Proxmox

На машине с Proxmox выполним

pveum role add TerraformProv -privs "Datastore.AllocateSpace Datastore.Audit Pool.Allocate Sys.Audit Sys.Console Sys.Modify VM.Allocate VM.Audit VM.Clone VM.Config.CDROM VM.Config.Cloudinit VM.Config.CPU VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options VM.Migrate VM.Monitor VM.PowerMgmt"

pveum user add terraform-prov@pve --password ArVrRT16787 // пароль тестовый, на проде так не делаем, помним об этом

pveum aclmod / -user terraform-prov@pve -role TerraformProv

Теперь через веб-интерфейс создадим токен

ВАЖНО
— отключаем как на скриншоте ниже “privilege separation” (иначе terraform потом будет ругаться)
— обязательно сохраните токен

Токен можно создать и через CLI, но у меня постоянно выдавал ошибку, пока не сделал тоже самое, но через веб

В веб-интерфейсе Datacenter -> API Tokens -> Add -> user выбираем нашего пользователя, которого создали -> снимаем галочку с privilege separation -> Token ID infra -> Add

Теперь подготовим файлы для Terraform

На машине с Terraform выполним

// подставьте свои значения, в том числе storage на Proxmox, токен, его адрес и тд

nano main.tf

terraform {
  required_providers {
    proxmox = {
      source = "telmate/proxmox"
      version = "3.0.1-rc1"
    }
  }
}

provider "proxmox" {
  pm_api_url = "https://proxmox.lan:8006/api2/json"

  pm_api_token_id = "XXX@pve!XXX"
  pm_api_token_secret = "XXXXXX"
  pm_tls_insecure = true
}

resource "proxmox_vm_qemu" "test_server" {
  count = 1 
  name = "test-vm-${count.index + 1}"
  target_node = var.proxmox_host
  clone = var.template_name
  agent = 1
  os_type = "cloud-init"
  cloudinit_cdrom_storage = "local-lvm"
  cores = 2
  sockets = 1
  cpu = "host"
  memory = 1024
  scsihw = "virtio-scsi-pci"
  bootdisk = "scsi0"

  disks {
    scsi {
      scsi0 {
        disk {
          size = 10
          storage = "local-lvm"
        }
      }
    }
  }

  network {
    model = "virtio"
    bridge = "vmbr0"
  }

  ipconfig0 = "ip=192.168.3.139/21,gw=192.168.0.10"

  ssh_user = "root"
  sshkeys = <<EOF
  ${var.ssh_key}
  EOF
}

// аналогично подставьте свои

nano variables.tf

variable "proxmox_host" { default = "pve-host" }

variable "template_name" { default = "debian-cloud" }

variable "ssh_key" { default = "ХХХ" } 

Далее на Proxmox подготовим template

wget https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2

virt-customize -a debian-12-genericcloud-amd64.qcow2 --install qemu-guest-agent --run-command 'systemctl start qemu-guest-agent.service && systemctl enable qemu-guest-agent.service'

virt-customize -a debian-12-genericcloud-amd64.qcow2 --truncate /etc/machine-id

qm create 7100 --memory 2048 --name debian-cloud --net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-pci

qm importdisk 7100 debian-12-genericcloud-amd64.qcow2 local-lvm

qm set 7100 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-7100-disk-0   

qm set 7100 --ide2 local-lvm:cloudinit

qm set 7100 --boot order=scsi0

qm set 7100 --serial0 socket --vga serial0

qm set 7100 --agent enabled=1

qm template 7100

Теперь на машине с Terraform

terraform init

terraform validate

terraform plan

terraform apply

yes

Видим, что возникает ошибка

Error: 403 Permission check failed (/sdn/zones/localnetwork/vmbr0, SDN.Use)

Правим на Proxmox 

pveum acl modify / -user terraform-prov@pve -role PVESDNUser

Проверяем еще раз 

terraform apply

yes

Ждем, видим

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Проверяем

sysadmin@fedora:~$ ssh debian@192.168.3.139
Linux test-vm-1 6.1.0-21-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.90-1 (2024-05-03) x86_64

debian@test-vm-1:~$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

debian@test-vm-1:~$ ip a
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether da:2e:3c:7a:fc:4f brd ff:ff:ff:ff:ff:ff
    altname enp0s18
    altname ens18
    inet 192.168.3.139/21 brd 192.168.7.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::d82e:3cff:fe7a:fc4f/64 scope link 
       valid_lft forever preferred_lft forever

Чтобы уничтожить созданную ВМ

terraform destroy

yes

Destroy complete! Resources: 1 destroyed.

Как видите, создавать ВМ стало немного быстрее и удобнее.

Отмечу, что у данного плагина есть определенные нюансы в плане различия версий и написания конфига, поэтому в самом начале я и указал все версии, какие использовал.

В нашем случае это тестовый вариант и в идеале хранение паролей, да и в целом организация конфига для IaC на проде выглядит по-другому, но для быстрой демонстрации возможностей, вполне подойдет.

Удачной автоматизации.