Skip to content

Information

I have been lurking at Infrastructure as Code (IaC) for a while. I am using a proxmox server at work to setup a small network that i use to teach network security.
At the moment everything is very manual with a lot of clicking around in the proxmox gui and the VM command lines.

My goal is to be able to spin up an entire lab environment in a few minutes using terraform to provision infrastructure and Ansible to configure hosts and network devices.
My journey towards this begins with a writeup of the video by Learn Linux TV:
Provisioning Virtual Machines in Proxmox with Terraform – Full Walkthrough
I did tweak the main.tf file to comply with recent changes to the provider plugin telmate/proxmox and no guarantees are made that this will work in your environment.

Consider this guide as a crude working example of using terraform to provision a vm in proxmox, and beware that you probably need to tweak it to your needs, before using it.

There are a few prerequisites:

  • proxmox server
  • proxmox VM template

Proxmox permissions and access token

  1. Copy the URL of your proxmox server ie. https://10.10.10.10:8006
  2. Copy name of the VM template ie. debian-12

Setup proxmox ressources

  1. click datacenter
  2. go to users
  3. add user - do not configure anything other than the name TerraformUser Proxmox add user
  4. go to roles
  5. create new role call it TerraformProvision and add these permissions:
    Datastore.AllocateSpace
    Datastore.Audit
    Pool.Allocate
    SDN.Use
    Sys.Audit
    Sys.Console
    Sys.Modify
    Sys.PowerMgmt
    VM.Allocate
    VM.Audit
    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 
    
    Proxmox create role
  6. click groups
  7. create a group called TerraformPermissions
  8. click permissions -> add group permissions
    Proxmox add group permissions
  9. add the following:
    Proxmox add group permissions
  10. edit TerraformUser and add group TerraformPermissions to it Proxmox add group to user

Create proxmox API token

  1. Click API tokens
  2. Select the TerraformUser
  3. Give the Token a name ie. TerraformToken
  4. Uncheck Privelege separation
  5. Click Add
    Proxmox create API token
  6. Save the Token ID and the Secret in a safe place like your vault or password manager
    DO NOT EXPOSE THIS IN A GIT REPO OR OTHER PUBLIC PLACE
    Proxmox create API token

Terraform setup and VM configuration

These steps sets up terraform on a local Linux machine, this can be a VM or physical machine.
After setup of terraform the creation of a VM using terraform is explained.

Prepare Terraform on local machine

TODO: Add section about protecting secrets from version control

  1. go to https://developer.hashicorp.com/terraform/install
  2. copy the download link that fits your processor, ie. AMD64
  3. switch to a linux terminal and WGET the link
    wget terraform
  4. use the terminal to unzip the downloaded file
    unzip terraform
  5. if on a multi user system you can change ownership to ie. root with chown root:root terraform
    chown terraform
    chown terraform root
  6. To use the terraform command you need to move the file with the command
    sudo mv terraform /usr/local/bin/
  7. Check that the path is recognized by typing command -v terraform and confírm that the output is /usr/local/bin/terraform (this confirms that the terraform command is available)
    terraform move and test command

Create terraform files

  1. create a directory for terraform in the home directory mkdir ~/terraform
  2. create a file called main.tf in the ~/terraform directory
  3. open the main.tf file in your favorite editor and add the following:
    main.tf
    terraform {
        required_providers {
            proxmox = {
                source = "telmate/proxmox"
                version = "3.0.1-rc6" // https://registry.terraform.io/telmate/proxmox  
            }
        }
    }
    
    provider "proxmox" {
        pm_api_url          = "https://url-to-proxmox-server:8006/api2/json"
        pm_api_token_id     = "your-token-id"
        pm_api_token_secret = "your-secret"
        pm_tls_insecure     = true
    }
    
    resource "proxmox_vm_qemu" "vm-instance" {
        name                = "vm-instance"
        target_node         = "your-proxmox-node-name"
        clone               = "your-template-name"
        full_clone          = true
        cores               = 2
        memory              = 2048
    
        disk {
            slot            = "scsi0"
            size            = "32G"
            type            = "disk"
            storage         = "your-storage-volume"
            discard         = "true"
        }
    
        network {
            model     = "virtio"
            bridge    = "vmbr1"
            firewall  = false
            link_down = false
            id        = 0
        }
    
    }
    
  4. replace the your-token-id and your-secret with the token id and secret from the previous steps
    DISCLAIMER: DO NOT EXPOSE TOKEN ID AND SECRET IN A GIT REPO OR OTHER PUBLIC PLACE
    PLEASE USE A VARIABLES FILE, ENVIRONMENT VARIABLES OR HASHICORP VAULT TO MANAGE THIS INFORMATION OUTSIDE OF VERSION CONTROL
    FOR ADDTIONAL INFORMATION SEE:
    https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables
  5. replace the your-proxmox-node-name with the name of your proxmox node
  6. replace the your-template-name with the name of your VM template
  7. check that the vmbr1 corresponds to your desired network bridge in proxmox

Run terraform

  1. go to the ~/terraform directory
  2. run terraform init
    terraform init
  3. run terraform plan to check what will be changed (this does not cjange anything in your proxmox node)
    terraform plan
  4. run terraform apply this will attempt to create the VM in proxmox
    terraform apply
  5. check that the VM is created in the proxmox GUI
    vm running