#!/usr/bin/env bash set -euo pipefail ACTION="${1:-}" if [[ -z "$ACTION" ]]; then echo "Usage: $0 " exit 1 fi # STACKS (optional, space/comma-separated stack dirs relative to live/, e.g. # "namespace rabbitmq vault-secrets") restricts the run to that subset. This # is the bootstrap escape hatch for cross-stack read dependencies that can't # plan until another stack has already been applied (e.g. a v2 secret with # ownership=referenced reading a value vault-secrets writes): the normal # "plan everything, abort on first error, apply only if plan was all-green" # pipeline can never apply anything on its own the first time around, since # the dependent stack's plan fails before apply ever runs. Set STACKS to just # the prerequisite stack(s) for one bootstrap run, then clear it back to # empty for normal full-pipeline runs. IFS=', ' read -r -a STACK_FILTER <<< "${STACKS:-}" should_run_stack() { local rel="${1#live/}" [[ ${#STACK_FILTER[@]} -eq 0 ]] && return 0 local s for s in "${STACK_FILTER[@]}"; do [[ -n "$s" && "$rel" == "$s" ]] && return 0 done return 1 } STACK_FILES=() while IFS= read -r tg; do STACK_FILES+=("$tg") done < <(find live -name 'terragrunt.hcl' -not -path '*/.terragrunt-cache/*' | sort) if [[ ${#STACK_FILES[@]} -eq 0 ]]; then echo "No terragrunt stacks found under live/" exit 0 fi for tg in "${STACK_FILES[@]}"; do stack_dir="$(dirname "$tg")" # Skip only root-level Terragrunt configuration file (live/terragrunt.hcl). # Execute concrete stacks like live/ and live//. if [[ "$stack_dir" == "live" ]]; then continue fi if ! should_run_stack "$stack_dir"; then echo "=== SKIP (not in STACKS filter): ${stack_dir} ===" continue fi echo "=== STACK: ${stack_dir} ===" ( cd "$stack_dir" terragrunt init -upgrade -reconfigure if [[ "$ACTION" == "validate" ]]; then terragrunt validate elif [[ "$ACTION" == "plan" ]]; then terragrunt plan -out=tfplan elif [[ "$ACTION" == "apply" ]]; then terragrunt apply -auto-approve else echo "Unknown action: $ACTION" exit 1 fi ) done