Files
jakman85andClaude Opus 4.8 53ca698edc 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]>
2026-08-25 10:23:13 -05:00

49 lines
2.0 KiB
Terraform

# versions.tf — OpenTofu + provider pins (Proxmox migration, R-ENV-01).
#
# Toolchain is pinned to match the dev container (infra/devcontainer/versions.env):
# OpenTofu 1.9.0. The node provider is now bpg/proxmox (the modern, maintained
# Proxmox VE provider — NOT telmate), pinned HERE, replacing dmacvicar/libvirt.
#
# AUTHOR-ONLY: this module is written but NOT applied. The PM static-validates
# with `tofu fmt -check` / `tofu validate`, then runs plan/apply against Proxmox.
terraform {
required_version = "1.9.0"
required_providers {
proxmox = {
source = "bpg/proxmox"
version = "~> 0.66"
}
}
}
locals {
# Endpoint normalization: the operator's env file may export PROXMOX_VE_ENDPOINT
# WITHOUT the https:// scheme (e.g. "192.168.2.102:8006"). If the provider is
# handed a schemeless/HTTP endpoint it talks to :8006 over plain HTTP and eats a
# 301 redirect. So if var.proxmox_endpoint is set we prepend https:// when the
# scheme is missing. When the variable is unset (null/empty) we return null and
# let the provider fall back to its own PROXMOX_VE_ENDPOINT env read.
#
# RUNBOOK: to get normalization, source the env file AND export the tofu var, e.g.
# export TF_VAR_proxmox_endpoint="$PROXMOX_VE_ENDPOINT"
# (or set proxmox_endpoint in terraform.tfvars). See README.
proxmox_endpoint = (
var.proxmox_endpoint == null || var.proxmox_endpoint == ""
? null
: (can(regex("^https?://", var.proxmox_endpoint)) ? var.proxmox_endpoint : "https://${var.proxmox_endpoint}")
)
}
provider "proxmox" {
# Auth is read from the environment by the provider itself and is NEVER surfaced
# as a tofu variable, so the API token never lands in state, vars, or plan output:
# PROXMOX_VE_API_TOKEN = "user@realm!tokenid=secret"
#
# endpoint/insecure are set explicitly (below) so we control scheme normalization;
# when proxmox_endpoint is null the provider still auto-reads PROXMOX_VE_ENDPOINT.
endpoint = local.proxmox_endpoint
insecure = var.proxmox_insecure
}