diff --git a/deploy/terraform/apps/starter/deploy.ps1 b/deploy/terraform/apps/starter/deploy.ps1 index a832151e64..dd79df2627 100644 --- a/deploy/terraform/apps/starter/deploy.ps1 +++ b/deploy/terraform/apps/starter/deploy.ps1 @@ -41,6 +41,13 @@ $RepoRoot = (Resolve-Path "$ScriptDir/../../../..").Path $AppStackDir = Join-Path $ScriptDir 'app_stack' $EnvDir = Join-Path $ScriptDir "envs/$Environment/$Region" +# Each env/region gets its OWN Terraform data dir (backend pointer, providers, +# modules) instead of the shared app_stack/.terraform. Without this, two runs +# against different backends — e.g. a deploy in one region while another region +# is being destroyed — clobber each other's backend pointer mid-run, so the +# later `terraform output` reads the wrong state ("Output not found"). +$env:TF_DATA_DIR = Join-Path $AppStackDir ".terraform/$Environment-$Region" + function Die($msg) { Write-Error $msg; exit 1 } if (-not (Test-Path "$EnvDir/backend.hcl")) { Die "no backend.hcl for $Environment/$Region at $EnvDir" } @@ -61,6 +68,14 @@ if ($tfVersion -lt $MinTfVersion) { Die "Terraform >= $MinTfVersion required (found $tfVersion). Upgrade with e.g. 'choco upgrade terraform'." } +# Ask up front (before the long apply) whether to seed the acme/globex demo +# tenants. Skipped when already chosen (-SeedDemo), not migrating (-SkipMigrate), +# or running unattended (-AutoApprove / non-interactive) so CI never blocks. +if (-not $SeedDemo -and -not $SkipMigrate -and -not $AutoApprove -and [Environment]::UserInteractive) { + $ans = Read-Host 'Seed demo tenants (acme/globex) after migrating? [y/N]' + if ($ans -match '^[Yy]') { $SeedDemo = $true } +} + Write-Host "==> Deploying '$Environment' in $Region" # ---- 1. optional API image build/push -------------------------------------- diff --git a/deploy/terraform/apps/starter/deploy.sh b/deploy/terraform/apps/starter/deploy.sh index 33040b109e..3ab3a29aac 100755 --- a/deploy/terraform/apps/starter/deploy.sh +++ b/deploy/terraform/apps/starter/deploy.sh @@ -80,6 +80,13 @@ ENV_DIR="$SCRIPT_DIR/envs/$ENVIRONMENT/$REGION" [[ -f "$ENV_DIR/backend.hcl" ]] || die "no backend.hcl for $ENVIRONMENT/$REGION at $ENV_DIR" [[ -f "$ENV_DIR/terraform.tfvars" ]] || die "no terraform.tfvars for $ENVIRONMENT/$REGION at $ENV_DIR" +# Each env/region gets its OWN Terraform data dir (backend pointer, providers, +# modules) instead of the shared app_stack/.terraform — otherwise two runs against +# different backends (e.g. a deploy in one region while another is destroyed) +# clobber each other's backend pointer mid-run and `terraform output` then reads +# the wrong state. Absolute path so it is unaffected by `terraform -chdir`. +export TF_DATA_DIR="$APP_STACK_DIR/.terraform/$ENVIRONMENT-$REGION" + # ---- tooling preflight ------------------------------------------------------ for tool in terraform aws jq; do command -v "$tool" >/dev/null || die "$tool is required but not installed"; done @@ -88,6 +95,14 @@ if [[ "$(printf '%s\n%s\n' "$MIN_TF_VERSION" "$TF_VERSION" | sort -V | head -1)" die "Terraform >= $MIN_TF_VERSION required (found $TF_VERSION). Upgrade with e.g. 'choco upgrade terraform'." fi +# Ask up front (before the long apply) whether to seed the acme/globex demo +# tenants. Skipped when already chosen (--seed-demo), not migrating +# (--skip-migrate), or running unattended (--auto-approve / no TTY) so CI never blocks. +if [[ "$SEED_DEMO" != true && "$SKIP_MIGRATE" != true && "$AUTO_APPROVE" != true && -t 0 ]]; then + read -rp "Seed demo tenants (acme/globex) after migrating? [y/N]: " ans + [[ "$ans" =~ ^[Yy] ]] && SEED_DEMO=true +fi + echo "==> Deploying '$ENVIRONMENT' in $REGION" # ---- 1. optional API image build/push -------------------------------------- diff --git a/deploy/terraform/apps/starter/destroy.ps1 b/deploy/terraform/apps/starter/destroy.ps1 index 3cf9985e81..47666d2ded 100644 --- a/deploy/terraform/apps/starter/destroy.ps1 +++ b/deploy/terraform/apps/starter/destroy.ps1 @@ -34,6 +34,10 @@ $ScriptDir = $PSScriptRoot $AppStackDir = Join-Path $ScriptDir 'app_stack' $EnvDir = Join-Path $ScriptDir "envs/$Environment/$Region" +# Per-env/region Terraform data dir so a destroy never clobbers (or is clobbered +# by) a concurrent deploy/destroy in another region sharing app_stack/.terraform. +$env:TF_DATA_DIR = Join-Path $AppStackDir ".terraform/$Environment-$Region" + function Die($msg) { Write-Error $msg; exit 1 } if (-not (Test-Path "$EnvDir/backend.hcl")) { Die "no backend.hcl for $Environment/$Region at $EnvDir" }