Automation

Provisioning Proxmox VMs with Terraform: Complete Guide

Learn how to use the Telmate Terraform provider for Proxmox VE to define, plan, and deploy virtual machines as code with API tokens, variables, and state management.

ProxmoxR app icon

Managing Proxmox? Try ProxmoxR

Monitor and control your VMs & containers from your phone.

Try Free

Terraform lets you define your Proxmox infrastructure as code — repeatable, version-controlled, and auditable. Instead of clicking through the web UI to create VMs, you write declarative configuration files and let Terraform handle the API calls. This guide walks through setting up the Telmate Proxmox provider, configuring API authentication, and deploying your first VM.

Prerequisites

You need Terraform installed on your workstation and a Proxmox VE node with API access. You should also have a VM template ready (a cloud-init enabled template works best with Terraform).

Setting Up a Proxmox API Token

Create a dedicated API token for Terraform rather than using your root credentials:

# On the Proxmox node, create a user for Terraform
pveum user add terraform@pve --comment "Terraform automation"

# Create a role with the necessary permissions
pveum role add TerraformRole -privs "VM.Allocate VM.Clone VM.Config.CDROM VM.Config.CPU VM.Config.Cloudinit VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options VM.Migrate VM.Monitor VM.PowerMgmt Datastore.AllocateSpace Datastore.Audit Pool.Allocate Sys.Audit Sys.Console Sys.Modify SDN.Use"

# Assign the role to the user
pveum aclmod / -user terraform@pve -role TerraformRole

# Create an API token (save the output — the secret is shown only once)
pveum user token add terraform@pve terraform-token --privsep=0

The --privsep=0 flag gives the token the same permissions as the user. Store the token ID and secret securely.

Terraform Provider Configuration

Create a project directory and configure the Proxmox provider:

# versions.tf
terraform {
  required_version = ">= 1.5.0"
  required_providers {
    proxmox = {
      source  = "Telmate/proxmox"
      version = "~> 3.0"
    }
  }
}

# provider.tf
provider "proxmox" {
  pm_api_url          = var.proxmox_api_url
  pm_api_token_id     = var.proxmox_api_token_id
  pm_api_token_secret = var.proxmox_api_token_secret
  pm_tls_insecure     = true  # Set to false if using valid SSL certs
}

Defining Variables

Keep sensitive values out of your configuration files using variables:

# variables.tf
variable "proxmox_api_url" {
  description = "Proxmox API URL"
  type        = string
  default     = "https://192.168.1.100:8006/api2/json"
}

variable "proxmox_api_token_id" {
  description = "Proxmox API token ID"
  type        = string
  sensitive   = true
}

variable "proxmox_api_token_secret" {
  description = "Proxmox API token secret"
  type        = string
  sensitive   = true
}

variable "vm_count" {
  description = "Number of VMs to create"
  type        = number
  default     = 3
}

Create a terraform.tfvars file (add it to .gitignore) with your actual credentials:

# terraform.tfvars
proxmox_api_token_id     = "terraform@pve!terraform-token"
proxmox_api_token_secret = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Defining a VM Resource

Here is a complete VM resource definition that clones from a template and uses cloud-init for guest configuration:

# main.tf
resource "proxmox_vm_qemu" "web_server" {
  count       = var.vm_count
  name        = "web-${count.index + 1}"
  target_node = "pve"
  clone       = "ubuntu-template"
  agent       = 1
  os_type     = "cloud-init"
  cores       = 2
  sockets     = 1
  memory      = 2048
  scsihw      = "virtio-scsi-single"
  bootdisk    = "scsi0"

  disks {
    scsi {
      scsi0 {
        disk {
          size    = "20G"
          storage = "local-lvm"
        }
      }
    }
  }

  network {
    model  = "virtio"
    bridge = "vmbr0"
  }

  # Cloud-init settings
  ipconfig0  = "ip=192.168.1.${110 + count.index}/24,gw=192.168.1.1"
  nameserver = "8.8.8.8"
  ciuser     = "admin"
  sshkeys    = file("~/.ssh/id_rsa.pub")

  lifecycle {
    ignore_changes = [
      network,
    ]
  }
}

Plan, Apply, and Manage State

Initialize the project and deploy:

# Initialize Terraform and download the provider
terraform init

# Preview what will be created
terraform plan

# Apply the configuration (creates the VMs)
terraform apply

# View current state
terraform state list

# Show details of a specific resource
terraform state show proxmox_vm_qemu.web_server[0]

# Destroy all managed resources
terraform destroy

State Management Best Practices

The Terraform state file contains your infrastructure mapping. For team environments, use a remote backend:

# Add to versions.tf for S3-compatible backend
terraform {
  backend "s3" {
    bucket   = "terraform-state"
    key      = "proxmox/terraform.tfstate"
    endpoint = "https://minio.local:9000"
    region   = "us-east-1"

    skip_credentials_validation = true
    skip_metadata_api_check     = true
    force_path_style            = true
  }
}

Practical Tips

  • Always run terraform plan before apply — review what will change
  • Use count or for_each for multiple similar VMs to avoid code duplication
  • Pin the provider version to avoid unexpected breaking changes
  • Never commit terraform.tfvars or state files to version control
  • Monitor your deployed VMs with ProxmoxR to track resource utilization after provisioning

Terraform with the Proxmox provider transforms VM management from a manual process into a repeatable workflow. Combined with cloud-init templates, you can spin up fully configured environments in minutes.

Take Proxmox management mobile

All the features discussed in this guide — accessible from your phone with ProxmoxR. Real-time monitoring, power control, firewall management, and more.

ProxmoxR

Manage Proxmox from your phone

Monitor, control, and manage your clusters on the go.

Free 7-day trial · No credit card required