infra(tofu): migrate node provisioning from libvirt to bpg/proxmox
Replace the dmacvicar/libvirt provider + resources with the modern bpg/proxmox provider. The dev cluster moves off the memory-constrained local libvirt host onto the Proxmox VE box. - versions.tf: pin bpg/proxmox ~> 0.66; provider reads auth from env (PROXMOX_VE_*, token never a tofu var) and normalizes a schemeless PROXMOX_VE_ENDPOINT (prepend https://) to avoid the :8006 HTTP 301. - variables.tf: Proxmox placement vars (node=proxmox, datastore=Storage, image_datastore=local, bridge=vmbr0); LAN 192.168.1.0/24 gw .1 DNS .18; node_ips .50/.51/.52; sizing 6 vCPU / 16384 MiB / 40+100 GiB; cpu_type host; Cilium VIP range .53-.60. - main.tf: proxmox_virtual_environment_download_file (cloud image -> local), per-node user-data snippet (proxmox_virtual_environment_file), and proxmox_virtual_environment_vm per node via name-keyed for_each (imported OS disk virtio0, blank data disk virtio1, native initialization ip_config + dns + user_data_file_id). - remove moved.tf (libvirt-specific count->for_each state migration). Authoring only; no apply. Traces R-ENV-01, R-PLAT-01. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
4f28ba6945
commit
53ca698edc
4 files changed
+229
-237
No files matched your search
+89
-45
@@ -1,17 +1,52 @@
|
||||
# variables.tf — every sizing / IP / image knob is a variable (Phase 1 T-1.1).
|
||||
# Defaults encode the LOCKED decisions in infra/PHASE1-SCOPE.md. Override via
|
||||
# terraform.tfvars (see terraform.tfvars.example).
|
||||
# variables.tf — every sizing / IP / image knob is a variable (Proxmox migration).
|
||||
# Defaults encode the migration target: 3 k3s nodes on the Proxmox VE box
|
||||
# (node "proxmox", 192.168.1.0/24 LAN). Override via terraform.tfvars (see
|
||||
# terraform.tfvars.example). Traces R-ENV-01 (reproducible node provisioning),
|
||||
# R-PLAT-01.
|
||||
|
||||
variable "libvirt_uri" {
|
||||
description = "libvirt connection URI."
|
||||
# --- Proxmox connection / placement ----------------------------------------
|
||||
|
||||
variable "proxmox_endpoint" {
|
||||
description = <<-EOT
|
||||
Proxmox VE API endpoint, e.g. "https://192.168.2.102:8006/". Optional: if unset
|
||||
the provider reads PROXMOX_VE_ENDPOINT from the environment directly. Set this
|
||||
(e.g. via `export TF_VAR_proxmox_endpoint="$PROXMOX_VE_ENDPOINT"`) to let tofu
|
||||
NORMALIZE a schemeless endpoint (prepend https://) — see versions.tf. The API
|
||||
TOKEN is NOT a variable; it is read from PROXMOX_VE_API_TOKEN by the provider so
|
||||
it never enters tofu state/vars.
|
||||
EOT
|
||||
type = string
|
||||
default = "qemu:///system"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "pool_name" {
|
||||
description = "libvirt storage pool for all volumes (base image, OS + data disks, seed ISOs)."
|
||||
variable "proxmox_insecure" {
|
||||
description = "Skip TLS verification for the Proxmox self-signed cert (also read from PROXMOX_VE_INSECURE)."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "proxmox_node" {
|
||||
description = "Proxmox VE node name that hosts the VMs (VERIFIED: proxmox)."
|
||||
type = string
|
||||
default = "default"
|
||||
default = "proxmox"
|
||||
}
|
||||
|
||||
variable "datastore" {
|
||||
description = "Datastore for VM OS + data disks (VERIFIED: Storage, ZFS 4.3TB, rootdir+images)."
|
||||
type = string
|
||||
default = "Storage"
|
||||
}
|
||||
|
||||
variable "image_datastore" {
|
||||
description = "Datastore that holds the downloaded cloud image / cloud-init snippets (VERIFIED: local, dir storage)."
|
||||
type = string
|
||||
default = "local"
|
||||
}
|
||||
|
||||
variable "bridge" {
|
||||
description = "Proxmox network bridge for the node NIC (VERIFIED: vmbr0, no VLAN tag)."
|
||||
type = string
|
||||
default = "vmbr0"
|
||||
}
|
||||
|
||||
# --- cluster identity / naming ---------------------------------------------
|
||||
@@ -39,50 +74,44 @@ variable "node_count" {
|
||||
}
|
||||
}
|
||||
|
||||
# --- per-node sizing (LOCKED: 4 vCPU / 6 GiB / 20 GiB OS + 40 GiB data) -----
|
||||
# --- per-node sizing (Proxmox target: 6 vCPU / 16 GiB / 40 GiB OS + 100 GiB data) --
|
||||
|
||||
variable "vcpu" {
|
||||
description = "vCPUs per node."
|
||||
description = "vCPUs (cores) per node. Generous — the box has plenty."
|
||||
type = number
|
||||
default = 4
|
||||
default = 6
|
||||
}
|
||||
|
||||
variable "memory_mib" {
|
||||
description = "RAM per node in MiB (6 GiB)."
|
||||
description = "RAM per node in MiB (16 GiB)."
|
||||
type = number
|
||||
default = 6144
|
||||
default = 16384
|
||||
}
|
||||
|
||||
variable "os_disk_gib" {
|
||||
description = "OS (root) disk size per node, GiB. Thin qcow2 backed by the cloud image."
|
||||
type = number
|
||||
default = 20
|
||||
}
|
||||
|
||||
variable "data_disk_gib" {
|
||||
description = "Dedicated Longhorn data disk per node, GiB. Thin qcow2, blank."
|
||||
description = "OS (root) disk size per node, GiB. Imported from the cloud image, on the Storage datastore."
|
||||
type = number
|
||||
default = 40
|
||||
}
|
||||
|
||||
variable "cpu_mode" {
|
||||
description = "libvirt CPU mode. host-passthrough exposes nested-virt for KubeVirt (Phase 5)."
|
||||
type = string
|
||||
default = "host-passthrough"
|
||||
variable "data_disk_gib" {
|
||||
description = "Dedicated Longhorn data disk per node, GiB. Blank, on the Storage datastore."
|
||||
type = number
|
||||
default = 100
|
||||
}
|
||||
|
||||
# --- network (LOCKED: dedicated NAT k3s-dev 10.73.0.0/24, gw .1) ------------
|
||||
|
||||
variable "network_name" {
|
||||
description = "libvirt NAT network name."
|
||||
variable "cpu_type" {
|
||||
description = "Proxmox vCPU type. `host` passes through the physical CPU (nested-virt for KubeVirt, Phase 5)."
|
||||
type = string
|
||||
default = "k3s-dev"
|
||||
default = "host"
|
||||
}
|
||||
|
||||
# --- network (Proxmox target: main LAN 192.168.1.0/24, gw .1, DNS PiHole .18) ---
|
||||
|
||||
variable "network_cidr" {
|
||||
description = "Cluster NAT subnet in CIDR. Gateway (network_gateway) is the libvirt bridge host IP."
|
||||
description = "Cluster subnet in CIDR (informational; nodes get static IPs from node_ips)."
|
||||
type = string
|
||||
default = "10.73.0.0/24"
|
||||
default = "192.168.1.0/24"
|
||||
}
|
||||
|
||||
variable "network_prefix" {
|
||||
@@ -92,45 +121,60 @@ variable "network_prefix" {
|
||||
}
|
||||
|
||||
variable "network_gateway" {
|
||||
description = "Default gateway / DNS for nodes = libvirt bridge host IP (LOCKED: 10.73.0.1)."
|
||||
description = "Default gateway for nodes (VERIFIED: 192.168.1.1, pfSense)."
|
||||
type = string
|
||||
default = "10.73.0.1"
|
||||
default = "192.168.1.1"
|
||||
}
|
||||
|
||||
variable "dns_server" {
|
||||
description = "DNS resolver for nodes (VERIFIED: 192.168.1.18, PiHole)."
|
||||
type = string
|
||||
default = "192.168.1.18"
|
||||
}
|
||||
|
||||
variable "node_ips" {
|
||||
description = "Static IPs per node, in order (LOCKED: .11/.12/.13)."
|
||||
description = "Static IPs per node, in order (VERIFIED: .50/.51/.52 on 192.168.1.0/24)."
|
||||
type = list(string)
|
||||
default = ["10.73.0.11", "10.73.0.12", "10.73.0.13"]
|
||||
default = ["192.168.1.50", "192.168.1.51", "192.168.1.52"]
|
||||
}
|
||||
|
||||
# Reserved for Cilium L2-announcement ingress VIPs (LOCKED: .240-.250).
|
||||
# Not materialised as libvirt objects; surfaced in outputs and kept OUT of any
|
||||
# DHCP range so nothing else claims them. Cilium's IP pool (WS-NET, Phase 2)
|
||||
# consumes this range.
|
||||
# Reserved for Cilium L2-announcement ingress VIPs (VERIFIED: .53-.60).
|
||||
# Not materialised as Proxmox objects; surfaced in outputs. Cilium's IP pool
|
||||
# (platform-config/cilium/l2-ip-pool.yaml) consumes this range.
|
||||
variable "cilium_l2_vip_range_start" {
|
||||
description = "First reserved Cilium L2 VIP."
|
||||
type = string
|
||||
default = "10.73.0.240"
|
||||
default = "192.168.1.53"
|
||||
}
|
||||
|
||||
variable "cilium_l2_vip_range_end" {
|
||||
description = "Last reserved Cilium L2 VIP."
|
||||
type = string
|
||||
default = "10.73.0.250"
|
||||
default = "192.168.1.60"
|
||||
}
|
||||
|
||||
# --- base OS image ----------------------------------------------------------
|
||||
|
||||
variable "image_source" {
|
||||
description = <<-EOT
|
||||
Source for the base OS volume: a URL or local path to a minimal cloud image
|
||||
(qcow2). Default is Debian 12 (bookworm) genericcloud amd64. Point at a local
|
||||
path to avoid re-downloading on every apply.
|
||||
Source URL for the base OS cloud image (qcow2), downloaded to image_datastore
|
||||
by proxmox_virtual_environment_download_file. Default is Debian 12 (bookworm)
|
||||
genericcloud amd64 — same image as the pre-migration libvirt module.
|
||||
EOT
|
||||
type = string
|
||||
default = "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2"
|
||||
}
|
||||
|
||||
variable "image_file_name" {
|
||||
description = <<-EOT
|
||||
File name the cloud image is stored as on image_datastore. Proxmox `iso`-content
|
||||
storage only accepts *.iso / *.img names, so a qcow2 URL must be saved with a
|
||||
.img extension (Proxmox still reads it as qcow2 on import).
|
||||
EOT
|
||||
type = string
|
||||
default = "debian-12-genericcloud-amd64.img"
|
||||
}
|
||||
|
||||
# --- cloud-init identity ----------------------------------------------------
|
||||
|
||||
variable "ssh_authorized_key" {
|
||||
|
||||
Reference in new issue
Block a user