Saltar al contenido principal

Terraform

La configuración de Terraform para el provider de bpg requiere un token y conexión vía SSH para usar todas las opciones.

Usuario + Token​

Acceder por SSH a un nodo para crear el usuario terraform y asignar roles.

pveum user add terraform@pve
pveum role add Terraform -privs "Datastore.Allocate Datastore.AllocateSpace Datastore.AllocateTemplate Datastore.Audit Pool.Allocate Pool.Audit Sys.Audit Sys.Console Sys.Modify SDN.Use 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 User.Modify"
pveum aclmod / -user terraform@pve -role Terraform
pveum user token add terraform@pve provider --privsep=0

Pool.Audit no es opcional. El pool de una VM no forma parte de su configuración, así que el provider lee la pertenencia listando GET /pools, y esa llamada sólo devuelve los pools sobre los que se tiene ese privilegio. Sin él no hay error: la respuesta es una lista vacía con HTTP 200, el provider da la VM por fuera de todo pool y guarda un pool_id vacío en el estado. El fallo aparece en el siguiente cambio de esa VM, cuando Terraform intenta añadirla a un pool en el que ya está:

Error: while adding VM 105 to pool prod: error updating pool: received an HTTP 500 response -
Reason: update pools failed: VM 105 is already a pool member

Si el rol ya existe, pveum role add falla: añadir el privilegio que falte sin tocar los demás se hace con -append.

pveum role modify Terraform -privs "Pool.Audit" -append

Se comprueba con el token, desde la máquina que ejecuta Terraform:

curl -sk -H "Authorization: PVEAPIToken=terraform@pve!provider=<secret>" \
https://<proxmox>:8006/api2/json/pools

La respuesta debe listar los pools donde viven las VMs. {"data":[]} con los pools creados significa que el privilegio sigue faltando, muestre lo que muestre la interfaz de Proxmox.

Debemos apuntar el token y añadirlo al prefijo según el formato: terraform@pve!provider=00000000-0000-0000-0000-000000000000

Usuario SSH​

Definir el usuario en cada nodo.

apt update
apt install sudo
sudo useradd -m terraform
sudo visudo

Añadir las siguientes líneas al final:

terraform ALL=(root) NOPASSWD: /sbin/pvesm
terraform ALL=(root) NOPASSWD: /sbin/qm
terraform ALL=(root) NOPASSWD: /usr/bin/tee
terraform ALL=(root) NOPASSWD: /var/lib/vz/*

Crear un public key y añadirlo a la configuración.

mkdir /home/terraform/.ssh
vi /home/terraform/.ssh/authorized_keys

Provider​

Tras ello, configuramos el provider.

provider.tf
terraform {
required_providers {
proxmox = {
source = "bpg/proxmox"
}
}
}

provider "proxmox" {
endpoint = var.proxmox_endpoint.endpoint
insecure = var.proxmox_endpoint.insecure

api_token = var.proxmox_auth.api_token
ssh {
agent = true
username = var.proxmox_auth.username
private_key = fileexists(var.proxmox_auth.private_key) ? file(var.proxmox_auth.private_key) : var.proxmox_auth.private_key
}
}

Las variables.

variable "proxmox_endpoint" {
description = "Proxmox endpoint"
type = object({
endpoint = string
insecure = bool
})
}

variable "proxmox_auth" {
description = "Proxmox authentication"
type = object({
api_token = string
username = string
private_key = string
})
sensitive = true
}

Este es un ejemplo del fichero de valores donde el fichero con la private key se encuentra en la misma carpeta.

terraform.tfvars
proxmox_endpoint = {
endpoint = "https://serverName:8006/"
insecure = true
}

proxmox_auth = {
api_token = "terraform@pve!provider=00000000-0000-0000-0000-000000000000"
username = "terraform"
private_key = "proxmox.ppk"
}