// Technical guide // IaC Updated:

Automating Proxmox VE:
Ansible and Terraform

Proxmox VE has a full REST API and API tokens — that is vendor documentation. The Terraform and Ansible you call that API with are community: provider bpg/proxmox in the Terraform registry, collection community.general in Ansible. Proxmox GmbH does not stamp those providers the way VMware stamps vmware/vsphere.

// Table of Contents
  1. API and tokens (official)
  2. Terraform: bpg/proxmox
  3. Ansible: community.general
  4. Cloud-init and images
  5. What not to automate blindly
  6. Tokens: narrow ACLs
  7. State, SDN and day zero
  8. pvesh and the API explorer
// 01 · API

API and tokens (official)

Every GUI action has an API counterpart. Token: user + token ID, ACL like a human, with 2FA on the human account and none on the bot (TFA and Automated Access in PBS/PVE). Do not put the root password in a pipeline. Keep ACL paths narrow: one pool, one storage, no Sys.Modify on the whole datacenter.

API docs live in the GUI (Datacenter → Permissions → API Tokens) and in pveum. That is the layer Terraform and Ansible sit on — not the other way around.

// 02 · Terraform

Terraform: bpg/proxmox

In the registry: bpg/proxmox (community). Older Telmate/proxmox still shows up in forks — new projects take bpg. It is not an official Proxmox GmbH provider. Keep state off the cluster. Resources: VMs, CTs, network, storage mapping — the scope is the provider version, not “everything the GUI can do”.

vSphere has official vmware/vsphere. PVE has no Proxmox-stamped equivalent. That belongs in the IaC project risks, not under the rug.

In practice we pin the provider version (the number in required_providers), review the changelog before upgrading, and do not mix Telmate with bpg in one state file. The PVE API is versioned; the community provider trails it. That is why cluster day zero and Ceph stay in a runbook, and Terraform takes guests, tags, bridges and VNets the provider actually supports.

// 03 · Ansible

Ansible: community.general

Modules community.general.proxmox, proxmox_kvm, proxmox_pct, proxmox_template call the same API. The collection is community (Ansible / contributors), not “Ansible certified Proxmox”. Fine for idempotent CT/VM create, snapshots, start/stop. It does not replace terraform state across twenty SDN layers. In practice Ansible calls the API idempotently for CT/VM, and Terraform holds the network and tags that belong in git. Two tools on the same object with no ownership split drift: GUI, Ansible and Terraform overwrite each other.

// 04 · Images

Cloud-init and images

PVE supports cloud-init on VMs (vendor/meta/network). Terraform and Ansible pass user-data. CT templates from pveam, cloud images from Linux vendors. Windows: cloudbase-init or sysprep in your own gold image — we do not promise “cloud-init like Debian”.

// 05 · Limits

What not to automate blindly

💡

In practice: API token + Terraform for guests and network, Ansible for packages inside VMs, GUI clicks left for Ceph/OSDs and cluster day zero.

// 06 · ACL

Tokens: narrow ACLs

API docs and pveum: a token is user + token ID, the same ACL paths as a human. 2FA on the operator account, no 2FA on the automaton (TFA and Automated Access). Root passwords stay out of CI. A separate token for Terraform (VM/CT/network), a separate one for Ansible (if it calls PVE at all), neither gets Datastore.Modify on PBS nor Sys.Modify on the whole datacenter “just in case”.

Ansible modules community.general.proxmox, proxmox_kvm, proxmox_pct, proxmox_template call the same API. They are not “Ansible certified Proxmox”. They fit CT/VM, snapshots, start/stop — not twenty SDN layers as the source of truth.

// 07 · IaC limits

State, SDN and day zero

Keep Terraform state off the cluster (S3/Git with a lock). The bpg provider does not cover “everything the GUI can do” — the scope depends on the version. Corosync, QDevice and Ceph OSDs stay on the day-zero runbook, not on apply at first boot without a quorum network. PBS: the backup token does not delete the datastore — see PBS and ransomware.

Cloud-init on VMs (vendor/meta/network) is in PVE; Windows is cloudbase-init or sysprep in your own image, not “cloud-init like Debian”. CT templates from pveam.

// 08 · API

pvesh and the API explorer

Every GUI action has a REST path. pvesh is the CLI client for that API on the node (get/set/create/delete/ls). The GUI explorer (Documentation → API Viewer) shows the same paths Terraform calls. That is the vendor layer. The bpg provider and the Ansible collection sit on top and can lag a new PVE release — hence version pins and a changelog review before upgrade.

An API token with 2FA on the human account and none on the bot (TFA and Automated Access) is in the PVE/PBS docs. Privilege separation: the token inherits the user’s ACL, but you can narrow it. A separate token for Terraform, a separate one for PBS backup — neither holds both worlds.

💡

In practice: cluster day zero, QDevice and Ceph OSDs stay in a runbook. Terraform takes guests and VNets the provider supports. Ansible — packages inside VMs. The GUI stays for incidents and for what the provider does not cover yet.

We’ll put IaC on Proxmox VE

Tokens, bpg/proxmox, Ansible and cloud-init — with an explicit note that the provider is community.

⚡ Free consultation → Proxmox implementation