What is Proxmox?
Proxmox is a environment for virtualisation, allowing for virtual compute instances such as virtual machines and containers to run. Proxmox is open source, and I have small Proxmox instance running in my home lab.
What is Terraform?
Terraform is a tool to help achieve Infrastructure as Code (IaC). I have used it previously when deploying IaC in cloud environments such as AWS and Azure.
I won’t be going through installing Proxmox in this post but will pick up on the required steps needed to use Terraform with Proxmox.
Proxmox: Generating an API Token
After logging into Proxmox, click ‘Datacentre’, then expand ‘Permissions’ and the option for ‘API Tokens’ should show. Click on ‘API Tokens’, and ‘Add’. Proxmox will want to know which user the API token represents and what to call it (Token ID). It will then generate a token secret. Copy this token secret, and keep it in a safe / secure place.
Proxmox: API URL
The API URL for your Proxmox instance is the regular URL of Proxmox with ‘/api2/json’ tagged at the end.
Terraform: Files
For this blog post I have created a three files:
- provider.tf
- creds.auto.tfvars
- ubuntuContainer.tf
Terraform Provider: Telmate
Terraform uses providers to understand what APIs it is talking to, and what options it can send. Telmate has developed their Proxmox Terraform and it is available from: https://registry.terraform.io/providers/Telmate/proxmox/3.0.1-rc8
I’ve set the provider details in the provder.tf file.

terraform {
required_providers {
proxmox = {
source = "telmate/proxmox"
version = "3.0.1-rc8"
}
}
}
variable proxmox_api_url {
type = string
}
variable proxmox_api_token_id {
type = string
}
variable proxmox_api_token_secret {
type = string
}
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
}
Terraform: Variables
I’m storing my Proxmox URL, Token ID and Token Secret in a separate variable file called “creds.auto.tfvars“, so that they do not show up in the code (helping keep them secret). Instead the Terraform code will reference the variables names, which will call them from the variable file when needed.
With all that in place a quick ‘terraform init’ initialises Terraform.
Note: I would recommend setting a remote for the lock file and state file if using in production environment.
Terraform: ubuntuContainer.tf
The ubuntuContainer.tf contains the infrastructure I want to deploy, which is a small container running Ubuntu (Linux) and will be called “tf-deployed“.
variable proxmox_node_name {
type = string
}
variable proxmox_container_password {
type = string
}
resource "proxmox_lxc" "tf-deployed" {
target_node = var.proxmox_node_name
hostname = "tf-deployed"
ostemplate = "local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst"
password = var.proxmox_container_password
unprivileged = true
cores = "1"
memory = "1024" //in Megebytes
start = true
// Terraform will crash without rootfs defined
rootfs {
storage = "local-lvm"
size = "8G"
}
network {
name = "eth0"
bridge = "vmbr0"
ip = "dhcp"
}
}
Terraform Plan, Terraform Apply
With all that in place, a quick “terraform plan” confirms that the deployment details and a “terraform deploy” successfully deploys a new Ubuntu container in my Proxmox environment.

A repository with the code for this blog post can be found at https://github.com/geektechdude/terraform_proxmox