This article documents using Hashicorp’s Terraform to deploy LXC containers on Proxmox VE virtualisation platform.
It is assumed that the Proxmox VE host has been setup, and Terraform has already been installed and configured on a workstation that can access the Proxmox VE host at TCP port 8006.
Summary of procedure
From Proxmox VE host
- Add role to Proxmox VE host for Terraform user account
- Add user account for Terraform
- Assign the newly created role to the new user account
- Generate API token for Terraform to authenticate with Proxmox VE
From Terraform workstation
- Create environmental variables for the API token ID and its secret
- Create Terraform configuration file usually named main.tf
- Initialise the Terraform environment
- Validate the Terraform configuration file
- Check the action plan
- Apply the action plan
- Optionally destroy the deployment
Detailed commands
From Proxmox VE host
# Add user role pveum role add TerraformProv -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.Monitor VM.Audit VM.PowerMgmt Datastore.AllocateSpace Datastore.Audit" # Add user account pveum user add terraform-prov@pve --password userpassword # Assign new role to the new account pveum aclmod / -user terraform-prov@pve -role TerraformProv # Generate API token for the new account pveum user token add terraform-prov@pve terraform-api-token --privsep 0
Note
When generating API token, make sure you save the secret straightway, because if you don’t there is no way to retrieve it later on.
From Terraform workstation
# Initialise terraform environment terraform init # validate terraform configuration file terraform validate # check the action plan (aka dry run) terraform plan # actually making changes terraform apply # destroy the environment terraform destroy
My main.tf file for creating a test LXC container
terraform {
required_providers {
proxmox = {
source = "telmate/proxmox"
version = "2.9.6"
}
}
}
provider "proxmox" {
pm_api_url = "https://pve-host.example.com:8006/api2/json"
pm_tls_insecure = true
pm_log_enable = true
pm_log_file = "terraform-plugin-proxmox.log"
pm_debug = true
pm_log_levels = {
_default = "debug"
_capturelog = ""
}
}
resource "proxmox_lxc" "terraform-test" {
target_node = "pve2"
hostname = "lxc-terraform-test"
ostemplate = "zfs-storage:vztmpl/debian-10-turnkey-core_16.0-1_amd64.tar.gz"
password = "password"
unprivileged = true
// Terraform will crash without rootfs defined
rootfs {
storage = "zfs-nvme"
size = "8G"
}
network {
name = "eth0"
bridge = "vmbr0"
ip = "dhcp"
}
}
Areas worth paying attention to
LXC container creation failed with error “HTTP/1.1 403 Permission check failed”
This was due to the that the API token generated from the Terraform user had the “Privilege separation” enabled by default. When it was enabled, the resultant privileges are the intersected ones between the privileges assigned directly to the token and the privileges assigned to the user account. Apparently there is none assigned directly to the token, hence the resultant privileges were effectively none. Disabling the “Privilege separation” fixed this issue.
When using API token the environment variable names cannot be changed
The name of environment variables PM_API_TOKEN_ID & PM_API_TOKEN_SECRET are hard-coded in the provider, they cannot be changed to anything else.