Terraform
Terraform is a "infrastructure as code" deployment tool. In a nutshell, Terraform allows you to define virtual machine configurations in HashiCorp Configuration Language (HCL) and then have Terraform do all the work of setting up these VMs for you automatically. The benefit of this approach is that your configs are declarative and any changes can be version controlled, are repeatable (idempotent too), and predictable.
Cheat sheet
There are 4 components to using Terraform:
| Description | Command |
|---|---|
| Initialize and setup any providers | terraform init
|
| Show any changes Terraform will do | terraform plan
|
| Apply the changes (create/modify/destroy) to VMs as required. | terraform apply
|
| Tear down everything | terraform destroy
|
Example use-case
Using Terraform with Proxmox
You can use Hashicorp's Terraform deployment tool to automatically provision virtual machines on Proxmox. After installing Terraform, follow the following steps to get your deployments working.
Setup Terraform
Terraform controls the Proxmox server using the Telmate Proxmox provider. For more information on each of the provider's options, review the documentation at https://registry.terraform.io/providers/Telmate/proxmox/latest/docs/resources/vm_qemu.
To quickly get started, we will:
- Install Terraform
- Setup an account with an API key on Proxmox. This account should have permissions to '/' as well as to any storage volumes it needs to create VMs on '/storage/data'. (TBD)
- We will use the following
main.tffile which will define the provider and provider configurations. The VM definitions are also included here. - Run
terraform initto set up the provider - Run
terraform planto plan the tasks - Run
terraform applyto create the VMs.
main.tf:
# Use Telmate proxmox provider
terraform {
required_providers {
proxmox = {
source = "telmate/proxmox"
version = "2.7.4"
}
}
}
# Configure the proxmox provider
provider "proxmox" {
pm_api_url = "https://proxox-server:8006/api2/json"
pm_api_token_id = "terraform@pam!terraform_token_id"
pm_api_token_secret = "e458e7bc-d8e6-4028-885b-d0896f4becfa"
pm_tls_insecure = true
}
# Define our first VM
resource "proxmox_vm_qemu" "test-vm" {
count = 1 # 0 will destroy the VM
name = "test-vm-${count.index + 1}" # count.index starts at 0. We want the VM to be named test-vm-1
target_node = var.proxmox_host # target proxmox host
clone = var.template_name # VM template to clone from
os_type = "cloud-init"
agent = 1
cores = 2
sockets = 1
cpu = "host"
memory = 2048
scsihw = "virtio-scsi-pci"
bootdisk = "sata0"
disk {
slot = 0
size = "10G"
type = "sata"
storage = "data"
iothread = 1
}
network {
model = "virtio"
bridge = "vmbr0"
}
lifecycle {
ignore_changes = [
network,
]
}
ipconfig0 = "ip=10.1.1.10${count.index + 1}/22,gw=10.1.1.1"
# sshkeys set using variables. the variable contains the text of the key.
sshkeys = <<EOF
${var.ssh_key}
EOF
}
vars.tf:
variable "ssh_key" {
default = "ssh-rsa ... "
}
# This should be the exact same name as your proxmox node name
variable "proxmox_host" {
default = "proxmox-server"
}
variable "template_name" {
default = "rocky85-template"
}
Issues with the apply step
I kept on getting "400 Parameter verification failed":
╷
│ Error: 400 Parameter verification failed.
│
│ with proxmox_vm_qemu.test-vm[0],
│ on main.tf line 20, in resource "proxmox_vm_qemu" "test-vm":
│ 20: resource "proxmox_vm_qemu" "test-vm" {
│
╵
The issues I encountered which triggered this error was:
- Incorrect host name for the Proxmox node
- Invalid values for the disk type (I tried changing
type = "scsi"totype = "sata") while leavingiothread = 1defined.
To help diagnose issues, review the provider's documentation and ensure the values you're using are appropriate. You may also want to enable additional logging by running with the TF_LOG=TRACE environment variable:
$ TF_LOG=TRACE terraform apply