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 # 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_private_key_path = "~/.ssh/id_ecdsa"
ssh_public_key = "ecdsa-sha2-nistp256 AAAA... luddie@shadowfax" ssh_public_key = "ecdsa-sha2-nistp256 AAAA... luddie@shadowfax"
vm_name = "debian-vm" # Add/remove entries to create/destroy VMs. Key = hostname.
vm_id = 100 # All fields are optional — defaults: cores=2, memory=2048, disk_size=20
vm_cores = 2 vms = {
vm_memory = 2048 "web-1" = {}
vm_disk_size = 20 "web-2" = {}
"db-1" = { cores = 4, memory = 4096, disk_size = 40 }
}
+10 -29
View File
@@ -1,5 +1,5 @@
variable "proxmox_api_token" { 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 type = string
sensitive = true sensitive = true
} }
@@ -11,35 +11,16 @@ variable "ssh_private_key_path" {
} }
variable "ssh_public_key" { variable "ssh_public_key" {
description = "SSH public key to inject into created VMs" description = "SSH public key injected into created VMs"
type = string type = string
} }
variable "vm_name" { variable "vms" {
description = "Name of the VM to create" description = "Map of VMs to create. Key becomes the VM hostname."
type = string type = map(object({
default = "debian-vm" cores = optional(number, 2)
} memory = optional(number, 2048)
disk_size = optional(number, 20)
variable "vm_id" { }))
description = "Proxmox VM ID (100-999 for regular VMs)" default = {}
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
} }
+12 -7
View File
@@ -1,7 +1,9 @@
resource "proxmox_virtual_environment_vm" "vm" { resource "proxmox_virtual_environment_vm" "vm" {
name = var.vm_name for_each = var.vms
name = each.key
node_name = "proxmox" node_name = "proxmox"
vm_id = var.vm_id # vm_id omitted — Proxmox auto-assigns the next available ID
clone { clone {
vm_id = 9001 # debian-12-cloud template vm_id = 9001 # debian-12-cloud template
@@ -13,12 +15,12 @@ resource "proxmox_virtual_environment_vm" "vm" {
} }
cpu { cpu {
cores = var.vm_cores cores = each.value.cores
type = "x86-64-v2-AES" type = "x86-64-v2-AES"
} }
memory { memory {
dedicated = var.vm_memory dedicated = each.value.memory
} }
scsi_hardware = "virtio-scsi-single" scsi_hardware = "virtio-scsi-single"
@@ -26,7 +28,7 @@ resource "proxmox_virtual_environment_vm" "vm" {
disk { disk {
datastore_id = "local-lvm" datastore_id = "local-lvm"
interface = "scsi0" interface = "scsi0"
size = var.vm_disk_size size = each.value.disk_size
discard = "on" discard = "on"
iothread = true iothread = true
} }
@@ -62,6 +64,9 @@ resource "proxmox_virtual_environment_vm" "vm" {
} }
} }
output "vm_ipv4_address" { output "vm_ip_addresses" {
value = proxmox_virtual_environment_vm.vm.ipv4_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"]
}
} }