infra(tofu): scaffold off-cluster R2 remote state (encrypted)

Local-only tfstate meant losing the workstation would strand a rebuild (apply
would try to recreate the 3 live nodes). Move state to Cloudflare R2, which sits
OUTSIDE the Proxmox->VM->cluster->Gitea chain, so a full cluster rebuild can still
read it; encrypted at rest via OpenTofu native AES-GCM.

Adds a partial s3 backend (R2 skip-flags), gitignored backend.hcl/.r2.env for the
account-specific + secret bits, their .example templates, and a migration+DR runbook.
Locking (use_lockfile) deferred to an OpenTofu >=1.10 bump (1.9.0 lacks it).
Migration (tofu init -migrate-state) runs once the operator provisions the R2 bucket.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
jakman85andClaude Opus 4.8 committed 2026-08-27 15:57:12 -05:00
1 parent 91c82d2756
commit 485b9e3888
5 files changed
+139

No files matched your search

+12
View File
@@ -0,0 +1,12 @@
# Copy to `backend.hcl` (gitignored) and fill in from your Cloudflare R2 bucket + API token.
# Passed to tofu via: source .r2.env && tofu init -backend-config=backend.hcl -migrate-state
#
# The R2 <ACCOUNT_ID> is the 32-hex string in your Cloudflare dashboard URL / R2 endpoint. It is
# not a credential, but is kept out of git here as defense-in-depth.
bucket = "homelab-tofu-state"
key = "k3s-dev/terraform.tfstate"
endpoints = {
s3 = "https://<ACCOUNT_ID>.r2.cloudflarestorage.com"
}