deploy hermes

This commit is contained in:
2026-05-25 20:21:24 -05:00
parent e309acd67d
commit be8e50d590
40 changed files with 2420 additions and 1159 deletions

View File

@@ -1,9 +1,9 @@
# ─── VM ID Convention ────────────────────────────────────────────────────────
# ─── 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 ─────────────────────────────────────────────────────────
# ─── Template Lookup ─────────────────────────────────────────────────────────
# Find the template VM ID by name on the clone node
data "proxmox_virtual_environment_vms" "templates" {
@@ -20,11 +20,17 @@ data "proxmox_virtual_environment_vms" "templates" {
}
}
# ─── VM Resource ─────────────────────────────────────────────────────────────
# ─── 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
name = var.hostname
vm_id = var.vm_id
node_name = var.target_node
description = "Provisioned by mk-labs pipeline on ${timestamp()}"
@@ -32,34 +38,65 @@ resource "proxmox_virtual_environment_vm" "vm" {
# 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
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
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
}
dns {
servers = var.dns_servers
domain = var.search_domain
}
datastore_id = var.datastore
}
datastore_id = var.datastore
}
# Network interface
network_device {
bridge = var.bridge
model = "virtio"
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.

View File

@@ -9,3 +9,12 @@
# datastore = "liberty-tree"
# proxmox_api_url = "https://fantasyland.local.mk-labs.cloud:8006"
# proxmox_api_token = "terraform@pve!terraform-token=your-token-secret-here"
#
# ─── PCIe Passthrough (GPU workloads only) ────────────────────────────────────
# pcie_passthrough_enabled = true
# pcie_device_id = "0000:03:00"
#
# ─── Data Disk (stateful workloads only) ──────────────────────────────────────
# data_disk_enabled = true
# data_disk_size = 128
# data_disk_datastore = "utilidor" # omit to match OS disk datastore

View File

@@ -1,4 +1,4 @@
# ─── Provider Authentication ─────────────────────────────────────────────────
# ─── Provider Authentication ─────────────────────────────────────────────────
variable "proxmox_api_url" {
type = string
@@ -11,7 +11,7 @@ variable "proxmox_api_token" {
sensitive = true
}
# ─── VM Identity ─────────────────────────────────────────────────────────────
# ─── VM Identity ───────────────────────────────────────────────────────────────
variable "vm_id" {
type = number
@@ -40,7 +40,7 @@ variable "search_domain" {
default = "mk-labs.net"
}
# ─── Proxmox Placement ──────────────────────────────────────────────────────
# ─── Proxmox Placement ────────────────────────────────────────────────────────
variable "clone_node" {
type = string
@@ -59,7 +59,7 @@ variable "datastore" {
default = "liberty-tree"
}
# ─── Template Selection ─────────────────────────────────────────────────────
# ─── Template Selection ───────────────────────────────────────────────────────
variable "template_name" {
type = string
@@ -78,7 +78,7 @@ variable "template_name" {
}
}
# ─── Network ─────────────────────────────────────────────────────────────────
# ─── Network ─────────────────────────────────────────────────────────────────
variable "vlan_id" {
type = number
@@ -114,4 +114,43 @@ variable "gateway" {
type = string
description = "Default gateway. Only used when use_dhcp = false."
default = "10.1.71.1"
}
}
# ─── PCIe Passthrough (optional) ──────────────────────────────────────────────
# When pcie_passthrough_enabled = true, the device at pcie_device_id is passed
# through to the VM. Used for GPU workloads (e.g. astro-orbiter / RX 5700).
# Requires vfio-pci bound on the host and IOMMU enabled.
variable "pcie_passthrough_enabled" {
type = bool
description = "When true, passes through the PCIe device at pcie_device_id to the VM."
default = false
}
variable "pcie_device_id" {
type = string
description = "PCIe device address to pass through (e.g. '0000:03:00'). Get from lspci on the host."
default = ""
}
# ─── Data Disk (optional) ─────────────────────────────────────────────────────
# When data_disk_enabled = true, a second disk is provisioned for application
# data. Ansible handles LVM setup, formatting, and mounting.
variable "data_disk_enabled" {
type = bool
description = "When true, provisions a second disk for application data storage."
default = false
}
variable "data_disk_size" {
type = number
description = "Size of the data disk in GB. Only used when data_disk_enabled = true."
default = 128
}
variable "data_disk_datastore" {
type = string
description = "Proxmox storage pool for the data disk. Defaults to var.datastore when empty."
default = ""
}