state: add SOPS-encrypted terraform state to git
- SOPS + age encrypts all 101 .tfstate files (JSON-aware: keys visible, values encrypted) - scripts/state-sync: encrypt/decrypt/commit wrapper - scripts/tg: auto-decrypt before ops, auto-encrypt+commit after apply/destroy - terragrunt.hcl: -backup=- prevents backup file accumulation - .gitignore: track .tfstate.enc, ignore plaintext .tfstate - Cleaned 964MB of stale backups (state/backups/, .backup files)
This commit is contained in:
parent
7ec627f365
commit
3583994efe
106 changed files with 279468 additions and 6 deletions
60
scripts/state-sync
Executable file
60
scripts/state-sync
Executable file
|
|
@ -0,0 +1,60 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
STATE_DIR="$REPO_ROOT/state/stacks"
|
||||
|
||||
cmd="${1:-help}"
|
||||
stack="${2:-}" # optional: operate on single stack
|
||||
|
||||
encrypt_state() {
|
||||
local dir="$1"
|
||||
local src="$dir/terraform.tfstate"
|
||||
local dst="$dir/terraform.tfstate.enc"
|
||||
[ -f "$src" ] || return 0
|
||||
# Only re-encrypt if state is newer than encrypted version
|
||||
if [ ! -f "$dst" ] || [ "$src" -nt "$dst" ]; then
|
||||
sops -e --input-type json --output-type json "$src" > "$dst"
|
||||
fi
|
||||
}
|
||||
|
||||
decrypt_state() {
|
||||
local dir="$1"
|
||||
local src="$dir/terraform.tfstate.enc"
|
||||
local dst="$dir/terraform.tfstate"
|
||||
[ -f "$src" ] || return 0
|
||||
sops -d --input-type json --output-type json "$src" > "$dst"
|
||||
}
|
||||
|
||||
case "$cmd" in
|
||||
encrypt)
|
||||
if [ -n "$stack" ]; then
|
||||
encrypt_state "$STATE_DIR/$stack"
|
||||
else
|
||||
for dir in "$STATE_DIR"/*/; do
|
||||
encrypt_state "$dir"
|
||||
done
|
||||
fi
|
||||
;;
|
||||
decrypt)
|
||||
if [ -n "$stack" ]; then
|
||||
decrypt_state "$STATE_DIR/$stack"
|
||||
else
|
||||
for dir in "$STATE_DIR"/*/; do
|
||||
decrypt_state "$dir"
|
||||
done
|
||||
fi
|
||||
;;
|
||||
commit)
|
||||
# Encrypt all changed state, then git add + commit
|
||||
"$0" encrypt
|
||||
cd "$REPO_ROOT"
|
||||
git add state/stacks/*/terraform.tfstate.enc
|
||||
if ! git diff --cached --quiet; then
|
||||
git commit -m "state: update encrypted terraform state"
|
||||
fi
|
||||
;;
|
||||
help)
|
||||
echo "Usage: state-sync {encrypt|decrypt|commit} [stack-name]"
|
||||
;;
|
||||
esac
|
||||
42
scripts/tg
42
scripts/tg
|
|
@ -1,10 +1,36 @@
|
|||
#!/usr/bin/env bash
|
||||
# scripts/tg — wrapper: inject -auto-approve for non-interactive apply
|
||||
# scripts/tg — wrapper: decrypt state before, encrypt+commit after mutating ops
|
||||
# Usage: scripts/tg apply --non-interactive
|
||||
# scripts/tg run --all -- plan
|
||||
# Auth: `vault login -method=oidc` (token at ~/.vault-token)
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
SYNC="$REPO_ROOT/scripts/state-sync"
|
||||
|
||||
# Determine stack name from cwd (relative to stacks/)
|
||||
STACK_NAME=""
|
||||
cwd="$(pwd)"
|
||||
stacks_dir="$REPO_ROOT/stacks"
|
||||
if [[ "$cwd" == "$stacks_dir"/* ]]; then
|
||||
# Get first path component relative to stacks/
|
||||
rel="${cwd#$stacks_dir/}"
|
||||
STACK_NAME="${rel%%/*}"
|
||||
fi
|
||||
|
||||
# Decrypt state before any operation
|
||||
if [ -n "$STACK_NAME" ] && [ -f "$REPO_ROOT/state/stacks/$STACK_NAME/terraform.tfstate.enc" ]; then
|
||||
"$SYNC" decrypt "$STACK_NAME"
|
||||
fi
|
||||
|
||||
# Detect if this is a mutating operation
|
||||
is_mutating=false
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
apply|destroy|import|state) is_mutating=true ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# If running apply with --non-interactive, add -auto-approve for Terraform
|
||||
args=("$@")
|
||||
has_apply=false
|
||||
|
|
@ -25,7 +51,17 @@ if $has_apply && $has_non_interactive; then
|
|||
new_args+=("-auto-approve")
|
||||
fi
|
||||
done
|
||||
exec terragrunt "${new_args[@]}"
|
||||
terragrunt "${new_args[@]}"
|
||||
else
|
||||
exec terragrunt "$@"
|
||||
terragrunt "$@"
|
||||
fi
|
||||
|
||||
# After mutating operations, encrypt and commit
|
||||
if $is_mutating && [ -n "$STACK_NAME" ]; then
|
||||
"$SYNC" encrypt "$STACK_NAME"
|
||||
cd "$REPO_ROOT"
|
||||
git add "state/stacks/$STACK_NAME/terraform.tfstate.enc"
|
||||
if ! git diff --cached --quiet; then
|
||||
git commit -m "state($STACK_NAME): update encrypted state"
|
||||
fi
|
||||
fi
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue