Provision Proxmox VMs with Terraform¶
Source: hybridops-terraform-gitmods · Git-sourced, not registry-published
Prerequisites: Proxmox VE 8.x · A cloneable template VM (cloud-init enabled for Linux) · Terraform >= 1.5.0 · bpg/proxmox >= 0.69.0
Modules at a glance¶
| Module | Use for |
|---|---|
proxmox/vm |
Single, individually significant VM (control node, database, core service) |
proxmox/vm-multi |
Homogeneous VM pools: Kubernetes nodes, worker fleets, clusters |
proxmox/lxc |
High-density Linux containers where kernel sharing is acceptable |
All three are consumed via Git source reference:
source = "git::https://github.com/hybridops-tech/hybridops-terraform-gitmods.git//proxmox/<module>?ref=<tag>"
1. Single VM (proxmox/vm)¶
module "ctrl_01" {
source = "git::https://github.com/hybridops-tech/hybridops-terraform-gitmods.git//proxmox/vm?ref=v0.1.1"
node_name = "hybridhub"
datastore_id = "local-lvm"
template_vm_id = 9002
vm_id = 102
vm_name = "control-node"
cpu_cores = 2
memory_mb = 4096
disk_size_gb = 32
nameservers = ["8.8.8.8"]
interfaces = [
{
bridge = "vmbr0"
vlan_id = 10
ipv4 = {
address = "10.10.0.11/24"
gateway = "10.10.0.1"
}
}
]
cloud_init_user_data = file("${path.module}/cloud-init.yaml")
tags = ["platform", "control-node", "dev"]
}
Multiple NICs: append entries to interfaces. Only one should carry gateway (typically NIC0):
interfaces = [
{ bridge = "vmbr0", vlan_id = 10, ipv4 = { address = "10.10.0.41/24", gateway = "10.10.0.1" } },
{ bridge = "vmbr0", vlan_id = 50, ipv4 = { address = "dhcp" } }
]
2. VM pool (proxmox/vm-multi)¶
One resource block provisions the whole pool via for_each over the vms map.
module "rke2_cp" {
source = "git::https://github.com/hybridops-tech/hybridops-terraform-gitmods.git//proxmox/vm-multi?ref=v0.1.1"
node_name = "hybridhub"
datastore_id = "local-lvm"
template_vm_id = 9002
vms = {
"rke2-cp-01" = { vm_id = 410, role = "control-plane" }
"rke2-cp-02" = { vm_id = 411, role = "control-plane" }
"rke2-cp-03" = { vm_id = 412, role = "control-plane" }
}
cpu_cores = 4
memory_mb = 8192
disk_size_gb = 80
nameservers = ["8.8.8.8"]
interfaces = [
{ bridge = "vmbr0", vlan_id = 10, ipv4 = { address = "dhcp", gateway = "10.10.0.1" } },
{ bridge = "vmbr0", vlan_id = 50, ipv4 = { address = "dhcp" } }
]
cloud_init_user_data = file("${path.module}/cloud-init.yaml")
tags = ["platform", "rke2", "control-plane", "dev"]
}
Per-VM overrides: set interfaces or cloud_init_user_data on individual entries in vms to override the module default for that VM only.
3. Windows VMs¶
Set os_type = "win10" (or "win11"). Cloud-init networking is not applied: NICs are attached and the guest boots with DHCP. Configure static addressing post-provisioning or via DHCP reservation.
module "win_workers" {
source = "git::https://github.com/hybridops-tech/hybridops-terraform-gitmods.git//proxmox/vm-multi?ref=v0.1.1"
os_type = "win10"
node_name = "hybridhub"
datastore_id = "local-lvm"
template_vm_id = 9100
vms = {
"win-worker-01" = { vm_id = 301, role = "worker" }
"win-worker-02" = { vm_id = 302, role = "worker" }
}
cpu_cores = 4
memory_mb = 8192
disk_size_gb = 80
interfaces = [
{ bridge = "vmbr0", vlan_id = 20, ipv4 = { address = "dhcp" } }
]
tags = ["platform", "workers", "windows"]
}
4. Terragrunt wiring¶
terraform {
source = "git::https://github.com/hybridops-tech/hybridops-terraform-gitmods.git//proxmox/vm-multi?ref=v0.1.1"
}
inputs = {
node_name = "hybridhub"
datastore_id = "local-lvm"
template_vm_id = 9002
cpu_cores = 4
memory_mb = 8192
disk_size_gb = 80
nameservers = ["8.8.8.8"]
vms = {
"rke2-cp-01" = { vm_id = 410, role = "control-plane" }
"rke2-cp-02" = { vm_id = 411, role = "control-plane" }
"rke2-cp-03" = { vm_id = 412, role = "control-plane" }
}
interfaces = [
{ bridge = "vmbr0", vlan_id = 10, ipv4 = { address = "dhcp", gateway = "10.10.0.1" } }
]
tags = ["platform", "rke2", "dev"]
}
5. HybridOps Pack¶
pack_ref:
id: proxmox-vm-multi@v0.1.1
source: "git::https://github.com/hybridops-tech/hybridops-terraform-gitmods.git//proxmox/vm-multi"
version: "v0.1.1"
Key outputs¶
| Output | Description |
|---|---|
vm_id / vm_ids |
Proxmox VM ID(s) |
ipv4_address / ipv4_addresses |
Primary IPv4 per VM (requires guest agent) |
mac_addresses |
MAC addresses per VM |
tags |
Tags applied |
References¶
- HOWTO – Packer Proxmox Template: build the template VM this module clones from
- HOWTO – Proxmox SDN with Terraform: set up the VNet fabric before provisioning VMs
- ADR-0101 – VLAN Allocation Strategy
- ADR-0102 – Proxmox as Intra-Site Core Router