61 lines
1.4 KiB
Text
61 lines
1.4 KiB
Text
|
|
#!/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
|