Managing Proxmox VMs and LXCs with Terraform

There are a few Proxmox provider implementations available on the Terraform registry, this post specifically uses this one: https://registry.terraform.io/providers/loeken/proxmox/latest/docs

Other implementations might behave slightly differently but …


This content originally appeared on DEV Community and was authored by Norm Dong

There are a few Proxmox provider implementations available on the Terraform registry, this post specifically uses this one: https://registry.terraform.io/providers/loeken/proxmox/latest/docs

Other implementations might behave slightly differently but I haven't tried. This particular implementation has a weird behavior: it tries to recreate the disk for a virtual machine when running terraform apply - which then fails on the server's side. Fortunately it doesn't stop me from creating more resources e.g. when I add a new LXC to the file, it will still create the LXC just fine, so it kinda "works".

Compared to other services that support IaC (e.g. an AWS EC2 instance), I'm not sure if it's this particular implementation, or if it's the API on Proxmox's side, the whole experience does not feel smooth. It wants to do some "updates" when I haven't changed a single letter, which then doesn't actually seem to change anything, again it mostly "works", and it's better than manually clicking through a few steps each time I want to create a new VM/LXC through the web UI, so it's good enough to me.

My Terraform file looks like this, hopefully it's helpful to you if you are trying to do something similar:

terraform {
  required_providers {
    proxmox = {
      source  = "loeken/proxmox"
      version = ">=2.9.0"
    }
  }
  required_version = ">= 0.14"
}

provider "proxmox" {
  # Default HTTPS port of Proxmox is 8006, yours might be different
  pm_api_url = "https://xxxx:8006/api2/json"
  # I thought this was required as my Proxmox server uses a self-signed certificate. But apparently it works without this set to true anyway
  #pm_tls_insecure = true
  # Obviously not the best practice, you should use environment variables PM_USER and PM_PASS instead. I only do this because I am in a home lab environment
  pm_user     = "root@pam"
  pm_password = "secureultrapluspromax"
}

# https://registry.terraform.io/providers/loeken/proxmox/latest/docs/resources/vm_qemu
resource "proxmox_vm_qemu" "resource_name_here" {
  name        = "VM name here"
  target_node = "Name of the node (under the Datacenter node)"
  vmid        = 200
  cores       = 16
  memory      = 65536 # MiB
  os_type     = "ubuntu"
  # The volume name under the target node "local", then the storage type "ISO Images", then the image's name
  iso         = "local:iso/ubuntu-24.10-live-server-amd64.iso"

  disk {
    type    = "scsi"
    size    = "50G"
    storage = "local-lvm"
  }

  network {
    bridge    = "vmbr0"
    firewall  = false
    link_down = false
    model     = "e1000"
  }
}

# https://registry.terraform.io/providers/loeken/proxmox/latest/docs/resources/lxc
resource "proxmox_lxc" "resource_name_here" {
  target_node = "Name of the node (under the Datacenter node)"
  hostname     = "hostname"
  # The volume name under the target node "local", then the storage type "CT Templates", then the template's name
  ostemplate   = "local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst"
  # Root password
  password     = "secureultrapluspromax"
  unprivileged = true
  vmid         = 201
  cores        = 4
  memory       = 4096 # MiB

  // Terraform will crash without rootfs defined
  rootfs {
    storage = "local-lvm"
    size    = "2G"
  }

  features {
    mount = "nfs"
  }

  # Comments from the provider's doc, I keep it here to remind myself of this weird bug
  # // NFS share mounted on host
  # // Without 'volume' defined, Proxmox will try to create a volume with
  # // the value of 'storage' + : + 'size' (without the trailing G) - e.g.
  # // "/srv/host/bind-mount-point:256".
  # // This behaviour looks to be caused by a bug in the provider.
  mountpoint {
    key     = "0"
    slot    = 0
    storage = "/mnt/mountpoint"
    volume  = "/mnt/mountpoint"
    mp      = "/mnt/data"
    # Unintuitively (and if I remember correctly), this does not work without specifying a size
    size    = "1T"
  }

  network {
    name   = "eth0"
    bridge = "vmbr0"
    ip     = "dhcp"
  }
}


This content originally appeared on DEV Community and was authored by Norm Dong


Print Share Comment Cite Upload Translate Updates
APA

Norm Dong | Sciencx (2025-01-17T02:03:05+00:00) Managing Proxmox VMs and LXCs with Terraform. Retrieved from https://www.scien.cx/2025/01/17/managing-proxmox-vms-and-lxcs-with-terraform/

MLA
" » Managing Proxmox VMs and LXCs with Terraform." Norm Dong | Sciencx - Friday January 17, 2025, https://www.scien.cx/2025/01/17/managing-proxmox-vms-and-lxcs-with-terraform/
HARVARD
Norm Dong | Sciencx Friday January 17, 2025 » Managing Proxmox VMs and LXCs with Terraform., viewed ,<https://www.scien.cx/2025/01/17/managing-proxmox-vms-and-lxcs-with-terraform/>
VANCOUVER
Norm Dong | Sciencx - » Managing Proxmox VMs and LXCs with Terraform. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/01/17/managing-proxmox-vms-and-lxcs-with-terraform/
CHICAGO
" » Managing Proxmox VMs and LXCs with Terraform." Norm Dong | Sciencx - Accessed . https://www.scien.cx/2025/01/17/managing-proxmox-vms-and-lxcs-with-terraform/
IEEE
" » Managing Proxmox VMs and LXCs with Terraform." Norm Dong | Sciencx [Online]. Available: https://www.scien.cx/2025/01/17/managing-proxmox-vms-and-lxcs-with-terraform/. [Accessed: ]
rf:citation
» Managing Proxmox VMs and LXCs with Terraform | Norm Dong | Sciencx | https://www.scien.cx/2025/01/17/managing-proxmox-vms-and-lxcs-with-terraform/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.