This guide will walk you through the process of setting up Terraform to deploy virtual machines on Proxmox.
- Setting up Proxmox API key
- Installing Terraform on Windows
- Using Visual Studio Code with Terraform
- Setting up Terraform init project folder
- Generating SSH key on Windows
- Setting up VMs
- Using Terraform commands
- Helpful Links
- Log in to your Proxmox web interface.
- Navigate to Datacenter -> Permissions -> API Tokens.
- Click "Add" to create a new API token.
- Select a user, give the token a name, and decide whether to restrict the token's privileges.
- Save the token ID and secret. You'll need these for Terraform. If these are misplaced you will have to create a new one.
-
Download the Terraform ZIP file for Windows from the official website.
-
Extract the ZIP file to a directory, e.g.,
C:\terraform
. -
Add the directory to your system's PATH:
- Right-click on 'This PC' and go to Properties -> Advanced system settings -> Environment Variables.
- Under System variables, find PATH, click Edit, then Add, and enter the path to your Terraform directory.
-
Open a new Command Prompt and test the installation:
terraform version
This should display the installed Terraform version.
Visual Studio Code (VS Code) is an excellent editor for working with Terraform configurations. To enhance your Terraform development experience in VS Code, install the following extensions:
-
HashiCorp Terraform (hashicorp.terraform)
- Provides syntax highlighting, IntelliSense, and other language features for Terraform files.
- Offers commands for Terraform operations directly from VS Code.
-
HashiCorp HCL (hashicorp.hcl)
- Adds language support for HashiCorp Configuration Language (HCL).
- Improves syntax highlighting and formatting for .tf and .tfvars files.
-
Checkov (bridgecrew.checkov)
- Scans cloud infrastructure configurations to find misconfigurations.
- Helps identify security and compliance issues in your Terraform code.
-
Create a new directory
Infra
for your Terraform project using VSCode. -
Create a file named
providers.tf
in this directory. -
Initialize the Terraform working directory:
terraform init
A .terraform.lock.hcl
file is generated.
-
Open PowerShell.
-
Generate a new SSH key pair:
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
-
Save the key in the default location or specify a custom path.
-
Set a passphrase (optional but recommended).
Edit your providers.tf
file to include the following sections:
terraform {
required_version = ">= 0.13.0"
required_providers {
proxmox = {
source = "telmate/proxmox"
version = ">= 2.9.14"
}
}
}
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
# (Optional) Skip TLS Verification
pm_tls_insecure = true
}
Create a new file in your project folder variables.tf
which will store all variables to be used in setup. The number of variables depend on the complexity of the implementation.
variable "proxmox_api_url" {
type = string
description = "The URL of the Proxmox API"
}
variable "proxmox_api_token_id" {
type = string
description = "The ID of the Proxmox API token"
}
variable "proxmox_api_token_secret" {
type = string
description = "The secret of the Proxmox API token"
sensitive = true
}
variable "proxmox_node" {
type = string
description = "The name of the Proxmox node"
}
variable "vm_iso" {
type = string
description = "The ISO file to use for the VM installation"
}
variable "ciuser" {
description = "Cloud init user"
type = string
}
variable "cipassword" {
description = "Cloud init user password"
type = string
sensitive = true
}
variable "ipconfig0" {
description = "IP configuration for the VM"
type = string
default = "ip=dhcp"
}
variable "ssh_key" {
description = "SSH public key for VM access"
type = string
}
It's recommended to use environment variables or a secrets.auto.tfvars
file for sensitive information. Here's an example secrets.auto.tfvars
:
proxmox_api_url = "https://[PROXMOX_IP_ADDRESS]:8006/api2/json" # Your Proxmox IP Address
proxmox_api_token_id = "[YOUR_API_TOKEN_ID]" # API Token ID
proxmox_api_token_secret = "[YOUR_API_TOKEN_SECRET]" # API Token Secret
proxmox_node = "[YOUR_PROXMOX_NODE_NAME]" # Name of your Proxmox node
vm_iso = "[STORAGE_NAME]:iso/[YOUR_ISO_FILE_NAME]" # Path to your VM ISO file
ciuser = "[YOUR_CLOUD_INIT_USERNAME]" # Cloud-init username
cipassword = "[YOUR_CLOUD_INIT_PASSWORD]" # Cloud-init password
ipconfig0 = "ip=dhcp" # IP configuration (DHCP in this case)
ssh_key = "[YOUR_SSH_PUBLIC_KEY]" # Your SSH public key
Then, create a new file in your project folder fresh-VM.tf
this will run and setup a new VM from an iso file located in var.vm_iso
. You would need to complete the setup manually.
resource "proxmox_vm_qemu" "fresh_vm" {
target_node = var.proxmox_node
vmid = "100"
name = "Fresh_VM"
desc = "First Ubuntu VM from terraform"
cpu = "host"
cores = 1
memory = 2048
scsihw = "virtio-scsi-pci"
disk {
size = "32G"
type = "scsi"
storage = "local-lvm"
}
network {
model = "virtio"
bridge = "vmbr0"
}
iso = var.vm_iso
boot = "cdn"
os_type = "Linux"
agent = 1
onboot = true
}
This will set up a VM using cloud init based on an existing VM.
resource "proxmox_vm_qemu" "clone_vm" {
target_node = var.proxmox_node
vmid = "101"
name = "Ubuntu-TF"
desc = "Ubuntu VM from terraform"
clone = "Fresh_VM"
cpu = "host"
cores = 1
memory = 2048
scsihw = "virtio-scsi-pci"
disk {
size = "32G"
type = "scsi"
storage = "local-lvm"
}
network {
model = "virtio"
bridge = "vmbr0"
}
iso = var.vm_iso
agent = 1
onboot = true
os_type = "cloud-init"
ciuser = var.ciuser
cipassword = var.cipassword
ipconfig0 = var.ipconfig0
sshkeys = <<EOF
${var.ssh_key}
EOF
}
Add this to your outputs.tf
to output the IP address of your created VM:
output "fresh_vm_ip" {
value = proxmox_vm_qemu.fresh_vm.default_ipv4_address
description = "The IP address of the created VM"
}
output "clone_vm_ip" {
value = proxmox_vm_qemu.clone_vm.default_ipv4_address
description = "The IP address of the created VM"
}
-
To check your configuration and see planned changes:
terraform plan
-
To apply your configuration and create resources:
terraform apply
-
To destroy all resources created by your Terraform configuration:
terraform destroy
-
Other useful commands:
terraform show
: Display the current stateterraform validate
: Check if your configuration is validterraform fmt
: Format your configuration files
Here are some helpful resources: