- Terraform: VM provisioning, Unifi DHCP, Technitium DNS - talhelper: cluster config for 6-node Talos cluster - Cilium 1.19.4 CNI with Talos-compatible security context - docs: city-hall setup guide and bootstrap runbook
152 lines
5.2 KiB
HCL
152 lines
5.2 KiB
HCL
# ─── fastpass Talos Cluster ───────────────────────────────────────────────────
|
|
#
|
|
# Provisions all infrastructure for the fastpass Kubernetes cluster:
|
|
# - Talos ISO download to Proxmox
|
|
# - 3 control plane VMs (space-mountain, big-thunder-mountain, splash-mountain)
|
|
# - 3 worker VMs (jungle-cruise, haunted-mansion, peter-pans-flight)
|
|
# - Unifi DHCP reservations (MAC → IP) for all 6 nodes
|
|
# - Technitium DNS A records for all 6 nodes + cluster VIP
|
|
#
|
|
# After apply:
|
|
# Run talhelper from city-hall to generate and apply machine configs.
|
|
# See talos/talhelper/ for cluster configuration.
|
|
#
|
|
# IP Allocation (10.1.71.64/26 — Container Orchestration):
|
|
# .65 — Kubernetes API VIP (Talos native VIP, not a VM)
|
|
# .66 — space-mountain (control plane, main-street-usa)
|
|
# .67 — big-thunder-mountain (control plane, tomorrowland)
|
|
# .68 — splash-mountain (control plane, fantasyland)
|
|
# .69 — jungle-cruise (worker, main-street-usa)
|
|
# .70 — haunted-mansion (worker, tomorrowland)
|
|
# .71 — peter-pans-flight (worker, fantasyland)
|
|
# .80-.99 — Cilium LB pool (managed by Cilium, not Terraform)
|
|
|
|
locals {
|
|
# Node definitions — single source of truth for the entire cluster.
|
|
# VM ID convention: {third_octet}{fourth_octet:03d}
|
|
nodes = {
|
|
"space-mountain" = {
|
|
role = "controlplane"
|
|
target_node = "main-street-usa"
|
|
ip_address = "10.1.71.66"
|
|
vm_id = 71066
|
|
cpu_cores = 4
|
|
memory_mb = 8192
|
|
disk_size = 50
|
|
}
|
|
"big-thunder-mountain" = {
|
|
role = "controlplane"
|
|
target_node = "tomorrowland"
|
|
ip_address = "10.1.71.67"
|
|
vm_id = 71067
|
|
cpu_cores = 4
|
|
memory_mb = 8192
|
|
disk_size = 50
|
|
}
|
|
"splash-mountain" = {
|
|
role = "controlplane"
|
|
target_node = "fantasyland"
|
|
ip_address = "10.1.71.68"
|
|
vm_id = 71068
|
|
cpu_cores = 4
|
|
memory_mb = 8192
|
|
disk_size = 50
|
|
}
|
|
"jungle-cruise" = {
|
|
role = "worker"
|
|
target_node = "main-street-usa"
|
|
ip_address = "10.1.71.69"
|
|
vm_id = 71069
|
|
cpu_cores = 8
|
|
memory_mb = 16384
|
|
disk_size = 100
|
|
}
|
|
"haunted-mansion" = {
|
|
role = "worker"
|
|
target_node = "tomorrowland"
|
|
ip_address = "10.1.71.70"
|
|
vm_id = 71070
|
|
cpu_cores = 8
|
|
memory_mb = 16384
|
|
disk_size = 100
|
|
}
|
|
"peter-pans-flight" = {
|
|
role = "worker"
|
|
target_node = "fantasyland"
|
|
ip_address = "10.1.71.71"
|
|
vm_id = 71071
|
|
cpu_cores = 8
|
|
memory_mb = 16384
|
|
disk_size = 100
|
|
}
|
|
}
|
|
}
|
|
|
|
# ─── Talos ISO ───────────────────────────────────────────────────────────────
|
|
# ISO is pre-uploaded to the shared 'templates' datastore (Ceph-backed,
|
|
# visible to all nodes). File ID format: <datastore>:iso/<filename>
|
|
|
|
locals {
|
|
talos_iso_file_id = "${var.iso_datastore}:iso/metal-amd64.iso"
|
|
}
|
|
|
|
# ─── Cluster Nodes ───────────────────────────────────────────────────────────
|
|
# Iterate over the node map and call the node module for each.
|
|
|
|
module "nodes" {
|
|
source = "../modules/node"
|
|
for_each = local.nodes
|
|
|
|
hostname = each.key
|
|
vm_id = each.value.vm_id
|
|
node_role = each.value.role
|
|
target_node = each.value.target_node
|
|
iso_file_id = local.talos_iso_file_id
|
|
cpu_cores = each.value.cpu_cores
|
|
memory_mb = each.value.memory_mb
|
|
disk_size = each.value.disk_size
|
|
datastore = var.datastore
|
|
bridge = var.bridge
|
|
}
|
|
|
|
# ─── Unifi DHCP Reservations ─────────────────────────────────────────────────
|
|
# Create a static MAC→IP reservation for each node.
|
|
# Reservations are created before VMs start so the IP is guaranteed
|
|
# on first DHCP broadcast.
|
|
|
|
resource "unifi_user" "nodes" {
|
|
for_each = local.nodes
|
|
|
|
name = each.key
|
|
mac = lower(module.nodes[each.key].mac_address)
|
|
fixed_ip = each.value.ip_address
|
|
|
|
note = "Managed by mk-labs Terraform — fastpass cluster ${each.value.role}"
|
|
|
|
depends_on = [module.nodes]
|
|
}
|
|
|
|
# ─── DNS A Records ───────────────────────────────────────────────────────────
|
|
# Create A records for all 6 nodes in the internal zone.
|
|
# The cluster VIP (.65) is managed by Talos natively — no VM, but still
|
|
# needs a DNS entry for kubectl and talhelper to resolve the endpoint.
|
|
|
|
resource "technitium_record" "nodes" {
|
|
for_each = local.nodes
|
|
|
|
zone = var.dns_zone
|
|
name = "${each.key}.${var.dns_zone}"
|
|
type = "A"
|
|
ttl = 300
|
|
value = each.value.ip_address
|
|
}
|
|
|
|
resource "technitium_record" "vip" {
|
|
zone = var.dns_zone
|
|
name = "${var.cluster_name}-api.${var.dns_zone}"
|
|
type = "A"
|
|
ttl = 300
|
|
value = "10.1.71.65"
|
|
}
|
|
|