Make VMs dynamic with for_each map — spin up/down any number by name

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ludwig Mey
2026-09-28 20:04:45 +13:00
co-authored by Claude Sonnet 4.6
parent b8ce272610
commit dad5376064
3 changed files with 31 additions and 43 deletions
+9 -7
View File
@@ -1,12 +1,14 @@
# Copy this to terraform.tfvars and fill in your values
# Copy to terraform.tfvars and fill in your values
# terraform.tfvars is gitignored
proxmox_api_token = "terraform@pve!terraform=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
proxmox_api_token = "root@pam!terraform=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
ssh_private_key_path = "~/.ssh/id_ecdsa"
ssh_public_key = "ecdsa-sha2-nistp256 AAAA... luddie@shadowfax"
vm_name = "debian-vm"
vm_id = 100
vm_cores = 2
vm_memory = 2048
vm_disk_size = 20
# Add/remove entries to create/destroy VMs. Key = hostname.
# All fields are optional — defaults: cores=2, memory=2048, disk_size=20
vms = {
"web-1" = {}
"web-2" = {}
"db-1" = { cores = 4, memory = 4096, disk_size = 40 }
}
+10 -29
View File
@@ -1,5 +1,5 @@
variable "proxmox_api_token" {
description = "Proxmox API token in the format user@realm!token_name=secret"
description = "Proxmox API token — format: user@realm!token_name=secret"
type = string
sensitive = true
}
@@ -11,35 +11,16 @@ variable "ssh_private_key_path" {
}
variable "ssh_public_key" {
description = "SSH public key to inject into created VMs"
description = "SSH public key injected into created VMs"
type = string
}
variable "vm_name" {
description = "Name of the VM to create"
type = string
default = "debian-vm"
}
variable "vm_id" {
description = "Proxmox VM ID (100-999 for regular VMs)"
type = number
default = 100
}
variable "vm_cores" {
type = number
default = 2
}
variable "vm_memory" {
description = "Memory in MiB"
type = number
default = 2048
}
variable "vm_disk_size" {
description = "Disk size in GiB"
type = number
default = 20
variable "vms" {
description = "Map of VMs to create. Key becomes the VM hostname."
type = map(object({
cores = optional(number, 2)
memory = optional(number, 2048)
disk_size = optional(number, 20)
}))
default = {}
}
+12 -7
View File
@@ -1,7 +1,9 @@
resource "proxmox_virtual_environment_vm" "vm" {
name = var.vm_name
for_each = var.vms
name = each.key
node_name = "proxmox"
vm_id = var.vm_id
# vm_id omitted — Proxmox auto-assigns the next available ID
clone {
vm_id = 9001 # debian-12-cloud template
@@ -13,12 +15,12 @@ resource "proxmox_virtual_environment_vm" "vm" {
}
cpu {
cores = var.vm_cores
cores = each.value.cores
type = "x86-64-v2-AES"
}
memory {
dedicated = var.vm_memory
dedicated = each.value.memory
}
scsi_hardware = "virtio-scsi-single"
@@ -26,7 +28,7 @@ resource "proxmox_virtual_environment_vm" "vm" {
disk {
datastore_id = "local-lvm"
interface = "scsi0"
size = var.vm_disk_size
size = each.value.disk_size
discard = "on"
iothread = true
}
@@ -62,6 +64,9 @@ resource "proxmox_virtual_environment_vm" "vm" {
}
}
output "vm_ipv4_address" {
value = proxmox_virtual_environment_vm.vm.ipv4_addresses
output "vm_ip_addresses" {
value = {
for name, vm in proxmox_virtual_environment_vm.vm :
name => [for ip in flatten(vm.ipv4_addresses) : ip if ip != "127.0.0.1"]
}
}