homelab/build/config/terraform/README.md
Russell Seymour 1250c9cef6
Some checks are pending
deploy / deploy (push) Waiting to run
Initial checkin of code for managing homelab
2026-08-24 20:52:36 +01:00

66 lines
2.8 KiB
Markdown

# 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:
```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=<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).