Files
infra-kit/mise-tasks/vault/bootstrap
T
stolzor 64be99308b
terraform / check (push) Canceled after 0s
Initial commit
2026-10-11 20:30:21 +03:00

109 lines
4.3 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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