diff --git a/infrastructure/vault/manifests/vault-init-configmap.yaml b/infrastructure/vault/manifests/vault-init-configmap.yaml index 6c8b83b..8274f51 100644 --- a/infrastructure/vault/manifests/vault-init-configmap.yaml +++ b/infrastructure/vault/manifests/vault-init-configmap.yaml @@ -26,7 +26,12 @@ data: # Helper: run vault CLI inside the vault pod vault_exec() { - kubectl -n "$VAULT_NS" exec "$VAULT_POD" -- env VAULT_ADDR=http://127.0.0.1:8200 vault "$@" + # -i forwards stdin - needed for the heredoc-piped `vault policy write + # NAME -` call below. Without it, `kubectl exec` never passes stdin + # through and vault sees an empty policy body. This was unreachable + # until the init-detection fix above (the script always failed earlier, + # every run, before ever getting this far). + kubectl -n "$VAULT_NS" exec -i "$VAULT_POD" -- env VAULT_ADDR=http://127.0.0.1:8200 vault "$@" } # --- Wait for vault-0 pod to be ready --- @@ -45,10 +50,26 @@ data: sleep 5 # --- Check init/seal status --- + # `vault status` legitimately exits non-zero for normal states (2 = sealed, + # still prints valid JSON) as well as real failures (1 = can't connect, no + # output). The old `|| echo '{}'` fallback couldn't tell those apart - it + # discarded valid "already initialized, just sealed" JSON on exit 2 too, + # which made this script wrongly conclude "not initialized" and attempt to + # re-init an already-initialized Vault (always fails: "Vault is already + # initialized"). Only fall back to {} when there's truly no output. echo "==> Checking Vault status..." - status_json="$(vault_exec status -format=json 2>/dev/null || echo '{}')" - initialized="$(echo "$status_json" | grep -o '"initialized":[a-z]*' | cut -d: -f2 || echo "")" - sealed="$(echo "$status_json" | grep -o '"sealed":[a-z]*' | cut -d: -f2 || echo "")" + status_json="$(vault_exec status -format=json 2>/dev/null)" + if [ -z "$status_json" ]; then + status_json="{}" + fi + # jq, not grep/cut - `vault status -format=json` pretty-prints with a space + # after each colon ("initialized": true), which the old grep -o + # '"initialized":[a-z]*' pattern never matched (no space in the pattern) - + # initialized/sealed silently parsed as empty strings on every run + # regardless of actual Vault state, which is the real reason this script + # always tried to re-init an already-initialized Vault. + initialized="$(echo "$status_json" | jq -r '.initialized // empty')" + sealed="$(echo "$status_json" | jq -r '.sealed // empty')" root_token="" unseal_key=""