IaC Automation Setup¶
One-time setup to make the homelab drivable with automation (Ansible and OpenTofu). Per-host steps (SSH keys, API tokens, baseline playbooks) live in each host's setup guide, linked below.
Pre-requisites¶
- Local dev environment set up, see Local Dev Setup
- OpnSense configured (VLANs, DNS overrides)
- Cloudflare account (R2 for OpenTofu state, DNS)
Automation Access¶
How automation connects to each type of host:
| Host type | Ansible connects as | OpenTofu uses | Set up in |
|---|---|---|---|
| Proxmox VE nodes | root (SSH key) |
automation@pve API token |
Proxmox Node Setup, Proxmox Cluster Setup |
| Proxmox Backup Server | root (SSH key) |
- | PBS Setup |
| NAS and other Debian hosts | automation (passwordless sudo) |
- | NAS Node Setup |
- PVE and PBS use root because the cluster needs root SSH between nodes and for QDevice setup, and Proxmox tooling (
pvecm,pveum,qm) assumes root. A sudo user wouldn't reduce exposure since root SSH has to stay enabled anyway. Root login is key-only, set bycommon_baseline_sshd_permit_root_login: prohibit-passwordin the group'sgroup_vars. - Plain Debian hosts use an
automationuser, created by Ansible on the first run (which connects as the personal account made during install). Root SSH stays disabled. - Ansible SSH user is set per group with
ansible_useriniac/ansible/inventory/<env>/group_vars/<group>.yml.
Secrets¶
Secrets are encrypted with SOPS + age in iac/secrets/<env>.sops.yaml. .sops.yaml in the repo root sets the age recipient for that path.
The age key lives at ~/.sops/homelab-keys.txt. To edit a secrets file:
The ansible-<env> and tofu-<env> wrapper commands decrypt the file and export these (see scripts/with-secrets.sh):
| Secrets key | Exported as | Used for |
|---|---|---|
proxmox.endpoint |
TF_VAR_proxmox_endpoint |
Proxmox API URL |
proxmox.token_id |
TF_VAR_proxmox_token_id |
Proxmox API token ID |
proxmox.token_secret |
TF_VAR_proxmox_token_secret |
Proxmox API token secret |
cloudflare.account_id |
TF_VAR_cloudflare_account_id |
Cloudflare account, R2 endpoint |
cloudflare.api_token |
TF_VAR_cloudflare_api_token |
Cloudflare DNS/zone token |
cloudflare.r2.bucket |
TF_VAR_cloudflare_r2_bucket |
OpenTofu state bucket |
cloudflare.r2.access_key_id |
AWS_ACCESS_KEY_ID |
R2 (S3-compatible) state backend |
cloudflare.r2.secret_access_key |
AWS_SECRET_ACCESS_KEY |
R2 (S3-compatible) state backend |
Proxmox API Token¶
OpenTofu uses a dedicated non-root Proxmox user with an API token, created once per standalone host or once per cluster. See Terraform API User and Token.
Cloudflare R2 Setup¶
For now will be using Cloudflare R2 as S3-compatible remote backend for OpenTofu state with one bucket per environment.
To setup:
- Create an R2 bucket.
- Create an R2 API token with read/write access to the bucket, and note the access key ID and secret access key.
- Add the bucket name, access key ID and secret access key to
iac/secrets/<env>.sops.yamlundercloudflare.r2.
Cloudflare DNS Setup¶
A separate token with permissions for the relevant zone and DNS settings.
- Create an account API token scoped to the zone(s) it manages.
- Add it to
iac/secrets/<env>.sops.yamlascloudflare.api_token, along withcloudflare.account_id.