#!/bin/bash set -euo pipefail # Usage: # ./scripts/inject-secrets.sh local # ./scripts/inject-secrets.sh staging # ./scripts/inject-secrets.sh prod ENV=${1:-local} OUTPUT_PATH=${2:-/tmp/config.generated.json} SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" TEMPLATE="$REPO_ROOT/config/$ENV/config.json" echo "==> Environment: $ENV" echo "==> Template: $TEMPLATE" echo "==> Output: $OUTPUT_PATH" # ■■ Validate template exists ■■ if [ ! -f "$TEMPLATE" ]; then echo "ERROR: Config template not found at $TEMPLATE" exit 1 fi # ■■ Load secrets ■■ if [ "$ENV" = "local" ]; then ENV_FILE="$REPO_ROOT/.env.local" if [ ! -f "$ENV_FILE" ]; then echo "ERROR: .env.local not found. Copy .env.local.example and fill in your values." exit 1 fi echo "==> Loading local env from $ENV_FILE" set -a source "$ENV_FILE" set +a else echo "==> Fetching secrets from AWS Secrets Manager" AWS_ARGS=( secretsmanager get-secret-value --secret-id "$ENV/fm-be/config" --query SecretString --output text ) if [ -n "${AWS_ENDPOINT_URL:-}" ]; then echo "==> Using custom AWS endpoint: $AWS_ENDPOINT_URL" AWS_ARGS+=(--endpoint-url "$AWS_ENDPOINT_URL") fi SECRET=$(aws "${AWS_ARGS[@]}") eval "$(echo "$SECRET" | jq -r 'to_entries | .[] | "export \(.key)=\(.value)"')" fi # ■■ Extract required variables from template ■■ REQUIRED_VARS=$(grep -o '\${[A-Z0-9_]\+}' "$TEMPLATE" | tr -d '${}' | sort -u) echo "==> Validating required variables..." MISSING=() EMPTY=() for var in $REQUIRED_VARS; do if [ -z "${!var+set}" ]; then MISSING+=("$var") elif [ -z "${!var}" ]; then EMPTY+=("$var") fi done if [ ${#MISSING[@]} -gt 0 ]; then echo "ERROR: The following variables are not set at all:" for v in "${MISSING[@]}"; do echo " - $v" done exit 1 fi if [ ${#EMPTY[@]} -gt 0 ]; then echo "WARNING: The following variables are set but empty:" for v in "${EMPTY[@]}"; do echo " - $v" done fi echo "==> All required variables are set" # ■■ Safe substitution (only replace known vars) ■■ VARS=$(printf '${%s} ' $REQUIRED_VARS) envsubst "$VARS" < "$TEMPLATE" > "$OUTPUT_PATH" echo "==> Config generated at $OUTPUT_PATH" # ■■ Validate JSON ■■ if ! jq empty "$OUTPUT_PATH" 2>/dev/null; then echo "ERROR: Generated config is not valid JSON" echo "==> jq diagnostics:" jq empty "$OUTPUT_PATH" || true rm -f "$OUTPUT_PATH" exit 1 fi echo "==> JSON validation passed" echo "==> Done."