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.

  • A proxmox window for adding a token. The window has fields for user, token id and comment.
  • The Proxmox API tokens screen showing a token has been created with a token name of terraform.

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.

A terraform file called provider.tf. The file contents show that telmate/proxmox is being used as a provider.
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 terminal output showing the successful run of a terraform apply command.

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