# 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 }