Initial commit
terraform / check (push) Canceled after 0s

This commit is contained in:
stolzor committed 2026-10-11 20:30:21 +03:00
commit 64be99308b
53 files changed
+1983

No files matched your search

+108
View File
@@ -0,0 +1,108 @@
#!/usr/bin/env bash
#MISE description="Токен Terraform для Vault, проверка политик, отзыв root-токена (нужен ROOT_TOKEN)"
set -euo pipefail
MOUNT=$VAULT_MOUNT
ENV_FILE=.env
KEYS_FILE=vault_keys.txt
REVOKE_ROOT=false
[[ "${1:-}" == "--revoke-root" ]] && REVOKE_ROOT=true
bao_as() {
local token=$1
shift
docker compose exec -T -e BAO_TOKEN="$token" vault bao "$@"
}
step() { printf '\n== %s\n' "$*"; }
ok() { printf ' ok: %s\n' "$*"; }
fail() {
printf ' ОШИБКА: %s\n' "$*" >&2
exit 1
}
ROOT_TOKEN=${ROOT_TOKEN:-$(sed -n 's/^Initial Root Token: *//p' "$KEYS_FILE" 2>/dev/null || true)}
[[ -n "$ROOT_TOKEN" ]] || fail "нет root-токена: задайте ROOT_TOKEN или положите $KEYS_FILE"
bao_as "$ROOT_TOKEN" token lookup >/dev/null 2>&1 || fail "root-токен не принят (отозван или Vault запечатан)"
step "Шаг 1. Токен для Terraform"
TF_TOKEN=${VAULT_TOKEN:-}
if [[ -n "$TF_TOKEN" ]] && bao_as "$TF_TOKEN" token lookup -format=json 2>/dev/null |
jq -e '.data.policies | index("terraform")' >/dev/null; then
ok "в $ENV_FILE уже есть рабочий токен, новый не создаю"
else
TF_TOKEN=$(bao_as "$ROOT_TOKEN" token create -orphan -policy=terraform -period=720h \
-display-name=terraform -format=json | jq -r .auth.client_token)
[[ -n "$TF_TOKEN" && "$TF_TOKEN" != null ]] || fail "токен не создан"
sed -i '/^VAULT_TOKEN=/d' "$ENV_FILE"
printf 'VAULT_TOKEN=%s\n' "$TF_TOKEN" >>"$ENV_FILE"
ok "токен создан и записан в $ENV_FILE как VAULT_TOKEN"
fi
bao_as "$TF_TOKEN" token lookup -format=json |
jq -r '.data | " политики: \(.policies | join(", ")); orphan: \(.orphan); period: \(.period)s"'
step "Шаг 2. terraform plan в vault/ с новым токеном"
set +e
TF_VAR_vault_token=$TF_TOKEN terraform -chdir=vault plan -input=false -no-color -detailed-exitcode >/tmp/vault-plan.$$ 2>&1
PLAN_EXIT=$?
set -e
case $PLAN_EXIT in
0) ok "No changes: политики terraform хватает" ;;
2)
grep -E '^ # |^Plan:' /tmp/vault-plan.$$ || true
rm -f /tmp/vault-plan.$$
fail "plan хочет что-то изменить, прочитайте его: terraform -chdir=vault plan"
;;
*)
grep -vE 'Refreshing state' /tmp/vault-plan.$$ | tail -30
rm -f /tmp/vault-plan.$$
fail "plan упал, скорее всего в политике terraform не хватает пути из ошибки выше"
;;
esac
rm -f /tmp/vault-plan.$$
step "Шаг 3. Границы сервисов через AppRole"
ROLES_JSON=$(terraform -chdir=vault output -json approle_role_ids)
mapfile -t SERVICES < <(jq -r 'keys[]' <<<"$ROLES_JSON")
cleanup() {
for svc in "${SERVICES[@]}"; do
bao_as "$ROOT_TOKEN" kv metadata delete -mount="$MOUNT" "$svc/bootstrap-check" >/dev/null 2>&1 || true
done
}
trap cleanup EXIT
for svc in "${SERVICES[@]}"; do
bao_as "$ROOT_TOKEN" kv put -mount="$MOUNT" "$svc/bootstrap-check" ok=1 >/dev/null
done
for svc in "${SERVICES[@]}"; do
role_id=$(jq -r --arg s "$svc" '.[$s]' <<<"$ROLES_JSON")
secret_id=$(bao_as "$ROOT_TOKEN" write -f -field=secret_id "auth/approle/role/$svc/secret-id")
svc_token=$(bao_as "$ROOT_TOKEN" write -field=token auth/approle/login role_id="$role_id" secret_id="$secret_id")
for target in "${SERVICES[@]}"; do
set +e
out=$(bao_as "$svc_token" kv get -mount="$MOUNT" "$target/bootstrap-check" 2>&1)
rc=$?
set -e
if [[ "$target" == "$svc" ]]; then
[[ $rc -eq 0 ]] || fail "$svc не читает свой путь $MOUNT/$target: $out"
ok "$svc читает $MOUNT/$target/*"
else
[[ $rc -ne 0 && "$out" == *"permission denied"* ]] || fail "$svc прочитал чужой путь $MOUNT/$target"
ok "$svc получает permission denied на $MOUNT/$target/*"
fi
done
bao_as "$svc_token" token revoke -self >/dev/null
done
step "Шаг 4. Root-токен"
if $REVOKE_ROOT; then
cleanup
trap - EXIT
bao_as "$ROOT_TOKEN" token revoke -self >/dev/null
ok "root-токен отозван; новый выпускается через bao operator generate-root с unseal-ключом"
else
ok "не отозван (запустите с --revoke-root, когда будете готовы)"
fi