Files
2026-05-25 20:21:24 -05:00

121 lines
3.9 KiB
HCL

# ─── VM ID Convention ─────────────────────────────────────────────────────────
# VM ID = {third_octet}{fourth_octet:03d}
# Example: 10.1.71.35 → 71035
# Computed by n8n and passed as a variable to keep the logic in one place.
# ─── Template Lookup ──────────────────────────────────────────────────────────
# Find the template VM ID by name on the clone node
data "proxmox_virtual_environment_vms" "templates" {
node_name = var.clone_node
filter {
name = "template"
values = ["true"]
}
filter {
name = "name"
values = [var.template_name]
}
}
# ─── Locals ───────────────────────────────────────────────────────────────────
locals {
data_disk_datastore = var.data_disk_datastore != "" ? var.data_disk_datastore : var.datastore
}
# ─── VM Resource ──────────────────────────────────────────────────────────────
resource "proxmox_virtual_environment_vm" "vm" {
name = var.hostname
vm_id = var.vm_id
node_name = var.target_node
description = "Provisioned by mk-labs pipeline on ${timestamp()}"
tags = ["managed", "pipeline"]
# Clone from template on fantasyland
clone {
vm_id = data.proxmox_virtual_environment_vms.templates.vms[0].vm_id
node_name = var.clone_node
full = true
datastore_id = var.datastore
}
# Cloud-init configuration
# Uses DHCP — Unifi DHCP reservation is created before VM starts
initialization {
ip_config {
ipv4 {
address = var.use_dhcp ? "dhcp" : "${var.ip_address}/${var.subnet_mask}"
gateway = var.use_dhcp ? null : var.gateway
}
}
dns {
servers = var.dns_servers
domain = var.search_domain
}
datastore_id = var.datastore
}
# Network interface
network_device {
bridge = var.bridge
model = "virtio"
}
# ─── PCIe Passthrough (optional) ────────────────────────────────────────────
# Only materialises when pcie_passthrough_enabled = true.
# Passes all functions of the device (VGA + Audio for AMD GPUs).
# Requires vfio-pci bound on host and IOMMU enabled.
dynamic "hostpci" {
for_each = var.pcie_passthrough_enabled ? [1] : []
content {
device = "hostpci0"
id = var.pcie_device_id
pcie = true
rombar = true
xvga = false
}
}
# ─── Data Disk (optional) ───────────────────────────────────────────────────
# Only materialises when data_disk_enabled = true.
# Ansible handles LVM setup, ext4 formatting, and mounting.
dynamic "disk" {
for_each = var.data_disk_enabled ? [1] : []
content {
datastore_id = local.data_disk_datastore
size = var.data_disk_size
interface = "scsi1"
file_format = "raw"
discard = "on"
}
}
# VM stays STOPPED after clone.
# n8n handles: DHCP reservation → HA affinity rule → VM start
# This ensures DHCP is in place before first boot.
started = var.started
# QEMU guest agent is installed in template (via Packer).
# Note: Proxmox 9 requires VM.GuestAgent.Audit privilege on the API token.
agent {
enabled = true
}
# Prevent Terraform from fighting with manual changes
lifecycle {
ignore_changes = [
description,
tags,
]
}
}