Skip to content

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