2.8 KiB
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/<app>/common/vars.yml + src/<app>/ansible/unraid/vars.yml |
src/<app>/common/vars.yml + src/<app>/ansible/proxmox/vars.yml |
Per-app LXC specs live in src/<app>/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:
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.
export TF_VAR_proxmox_endpoint='https://turtle-proxmox-01.home.turtlesystems.co.uk:8006/'
export TF_VAR_proxmox_api_token='root@pam!terraform=<secret>'
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).