66 lines
2.8 KiB
Markdown
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).
|