# build/config/terraform Centralized Terraform config for Proxmox — provider, backend, and the module calls that say what infrastructure exists. The counterpart to `build/config/ansible`, which holds inventory and the shared roles. ## Division of labour Terraform's job stops at the guest. It creates the LXC (template, cores, memory, disk, IP) and nothing more; Ansible then installs the app into it via the `lxc_app` role. That split is why Ansible is the common tool across both platforms and Terraform is Proxmox-only: | | Unraid | Proxmox | |---|---|---| | Provision the host | n/a — it already exists | Terraform (this directory) | | Install the app | Ansible + `compose_stack` (Docker Compose) | Ansible + `lxc_app` (native + systemd) | | App config | `src//common/vars.yml` + `src//ansible/unraid/vars.yml` | `src//common/vars.yml` + `src//ansible/proxmox/vars.yml` | Per-app LXC specs live in `src//terraform/` as modules, called from `main.tf` here. ## State `backend "pg"` — specifically against the **CloudNativePG cluster on the k3s Pis**, reached on its MetalLB address (`k3s_postgres_loadbalancer_ip`, 192.168.50.81). *Not* the shared Postgres this configuration itself provisions on Proxmox, which would be circular: Terraform would need the database to exist in order to create the container the database runs in. State goes somewhere Terraform has no hand in building, which breaks the cycle outright. Local state would make Terraform workstation-only; CI needs to see the same state. The connection string holds a password, so it is passed at init rather than committed: ```sh terraform init \ -backend-config="conn_str=postgres://terraform:$PG_PASSWORD@192.168.50.81:5432/terraform_state" ``` The bootstrap dependency this creates is on **k3s, not Unraid**: the cluster and its CNPG instance must be up, with a `terraform_state` database and a `terraform` role created on it, before `terraform init` works. That is the one cross-platform dependency the rest of the repo avoids, and it is deliberate — the alternative is a local-state-then-`init -migrate-state` dance that has to be got right exactly once. Ordering is in `docs/postgres-proxmox.md`. ## Credentials Proxmox API token and the Postgres connection string both come from Vault (`homelab/ci/proxmox`, `homelab/ci/terraform`), exported as environment variables before running — the same pattern `group_vars/all.yml` uses for `VAULT_ADDR` and friends. Nothing authenticating to anything is committed. ```sh export TF_VAR_proxmox_endpoint='https://turtle-proxmox-01.home.turtlesystems.co.uk:8006/' export TF_VAR_proxmox_api_token='root@pam!terraform=' ``` ## Status Not yet applied against anything. The provider version is intentionally unpinned until the first `terraform init` — pin what it resolves and commit `.terraform.lock.hcl` (which is not gitignored).