Preparation

I’ll assume you already have terraform installed and a VM template ready.

First of all, create a project directory:

mkdir proxmox-terraform
cd proxmox-terraform

Set up the project

Declare the usage of Proxmox provider:

vim main.tf
terraform {
  required_providers {
    proxmox = {
      source = "telmate/proxmox"
      version = "2.7.4"
    }
  }
}

Initialize Terraform:

terraform init

Create Terraform plan

Edit main.tf again:

terraform {
  required_providers {
    proxmox = {
      source = "telmate/proxmox"
      version = "2.9.14"
    }
  }
}

provider "proxmox" {
  pm_api_url = "<pve url>/api2/json"
  pm_api_token_id = "<token id>"
  pm_api_token_secret = "<token secret>"
}
resource "proxmox_vm_qemu" "test_server" {
  name = "test-vm"
  vmid = 201

  target_node = var.proxmox_host
  clone = var.template_name

  agent = 1
  os_type = "cloud-init"
  cores = 2
  sockets = 1
  cpu = "host"
  memory = 4096
  scsihw = "virtio-scsi-pci"
  bootdisk = "scsi0"
  disk {
    slot = 0
    size = "10G"
    type = "scsi"
    storage = "DATA"
#     iothread = 1 # currently broken
  }
  
  network {
    model = "virtio"
    bridge = "vmbr0"
  }

  lifecycle {
    ignore_changes = [
      network,
    ]
  }
  
  ipconfig0 = "ip=<ip address>/24,gw=<gateway ip>"
}

If your VM template doesn’t have authorized SSH keys set up remember to add them here!

Populate Terraform variables

vim vars.tf
variable "proxmox_host" {
    default = "pve"
}
variable "template_name" {
    default = "debian-12-cloudinit"
}

Remember to use proper values

Execute the plan

Before executing remember to verify the plan!

You can do so by running:

terraform plan

If everything looks good execute the plan:

terraform apply

Type yes to confirm and watch as your new VM is created. It will take a few minutes and if everything went right you’ll see:

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Removing the VM

This can also be done using terraform. Simply run:

terraform destroy

Sources

How to deploy VMs in Proxmox with Terraform