[infra] Migrate Terraform state from local SOPS to PostgreSQL backend
Two-tier state architecture: - Tier 0 (infra, platform, cnpg, vault, dbaas, external-secrets): local state with SOPS encryption in git — unchanged, required for bootstrap. - Tier 1 (105 app stacks): PostgreSQL backend on CNPG cluster at 10.0.20.200:5432/terraform_state with native pg_advisory_lock. Motivation: multi-operator friction (every workstation needed SOPS + age + git-crypt), bootstrap complexity for new operators, and headless agents/CI needing the full encryption toolchain just to read state. Changes: - terragrunt.hcl: conditional backend (local vs pg) based on tier0 list - scripts/tg: tier detection, auto-fetch PG creds from Vault for Tier 1, skip SOPS and Vault KV locking for Tier 1 stacks - scripts/state-sync: tier-aware encrypt/decrypt (skips Tier 1) - scripts/migrate-state-to-pg: one-shot migration script (idempotent) - stacks/vault/main.tf: pg-terraform-state static role + K8s auth role for claude-agent namespace - stacks/dbaas: terraform_state DB creation + MetalLB LoadBalancer service on shared IP 10.0.20.200 - Deleted 107 .tfstate.enc files for migrated Tier 1 stacks - Cleaned up per-stack tiers.tf (now generated by root terragrunt.hcl) [ci skip] Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f538115c43
commit
e80b2f026f
360 changed files with 844 additions and 302747 deletions
|
|
@ -24,6 +24,12 @@ stack_name_from_dir() {
|
|||
basename "$1"
|
||||
}
|
||||
|
||||
# Tier 0 stacks keep SOPS-encrypted local state; Tier 1 uses PG backend
|
||||
TIER0_STACKS="infra platform cnpg vault dbaas external-secrets"
|
||||
is_tier0() {
|
||||
echo "$TIER0_STACKS" | tr ' ' '\n' | grep -qx "$1"
|
||||
}
|
||||
|
||||
# Read age recipients from .sops.yaml
|
||||
AGE_RECIPIENTS="$(python3 -c "
|
||||
import yaml, sys
|
||||
|
|
@ -74,24 +80,38 @@ decrypt_state() {
|
|||
case "$cmd" in
|
||||
encrypt)
|
||||
if [ -n "$stack" ]; then
|
||||
encrypt_state "$STATE_DIR/$stack"
|
||||
if is_tier0 "$stack"; then
|
||||
encrypt_state "$STATE_DIR/$stack"
|
||||
else
|
||||
echo "state-sync: skipping Tier 1 stack '$stack' (PG backend)" >&2
|
||||
fi
|
||||
else
|
||||
for dir in "$STATE_DIR"/*/; do
|
||||
encrypt_state "$dir"
|
||||
_name="$(stack_name_from_dir "$dir")"
|
||||
if is_tier0 "$_name"; then
|
||||
encrypt_state "$dir"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
;;
|
||||
decrypt)
|
||||
if [ -n "$stack" ]; then
|
||||
decrypt_state "$STATE_DIR/$stack"
|
||||
if is_tier0 "$stack"; then
|
||||
decrypt_state "$STATE_DIR/$stack"
|
||||
else
|
||||
echo "state-sync: skipping Tier 1 stack '$stack' (PG backend)" >&2
|
||||
fi
|
||||
else
|
||||
for dir in "$STATE_DIR"/*/; do
|
||||
decrypt_state "$dir"
|
||||
_name="$(stack_name_from_dir "$dir")"
|
||||
if is_tier0 "$_name"; then
|
||||
decrypt_state "$dir"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
;;
|
||||
commit)
|
||||
# Encrypt all changed state, then git add + commit
|
||||
# Only Tier 0 stacks have encrypted state in git
|
||||
"$0" encrypt
|
||||
cd "$REPO_ROOT"
|
||||
git add state/stacks/*/terraform.tfstate.enc
|
||||
|
|
@ -101,6 +121,8 @@ case "$cmd" in
|
|||
;;
|
||||
help)
|
||||
echo "Usage: state-sync {encrypt|decrypt|commit} [stack-name]"
|
||||
echo "Operates on Tier 0 stacks only (infra, platform, cnpg, vault, dbaas, external-secrets)."
|
||||
echo "Tier 1 stacks use the PG backend and don't need local state sync."
|
||||
echo "Encrypt uses per-stack Vault Transit key (transit/keys/sops-state-<stack>)."
|
||||
echo "Decrypt uses Vault Transit if logged in, falls back to age key."
|
||||
;;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue