shoc-backend/terraform/live
Adam Moussa 25c2e84e8f feat(terraform): adopt live deployment roles safely
Add import-only dev and staging state with least-privilege HCP authentication and plan safety guards.
2026-08-28 19:12:34 -04:00
..
dev feat(terraform): adopt live deployment roles safely 2026-08-28 19:12:34 -04:00
modules feat(terraform): adopt live deployment roles safely 2026-08-28 19:12:34 -04:00
staging feat(terraform): adopt live deployment roles safely 2026-08-28 19:12:34 -04:00
README.md feat(terraform): adopt live deployment roles safely 2026-08-28 19:12:34 -04:00

Live deploy-role adoption

These roots replace CDK ownership of the existing GitHub Actions deploy roles. They do not create or manage Elastic Beanstalk, RDS, ACM, Route 53, VPC, subnets, security groups, runtime roles, instance profiles, or secrets.

Ownership

  • dev/ imports githubdeploy-shoc-backend-dev and its existing inline policy.
  • staging/ imports githubdeploy-shoc-backend-staging and its existing inline policy.
  • modules/environment-inventory/ reads and pins shared and environment resources without owning them.
  • ../bootstrap/ owns the four narrowly scoped live HCP Terraform plan/apply roles alongside the temporary POC role pair.

The shared shoc-backend Elastic Beanstalk application and shoc-sqlserver-shared RDS instance must never enter either environment state.

Two-phase adoption

Each live root pins adoption_complete=false in reviewed code. It is not an HCP workspace variable.

  1. Create the HCP workspace and configure dynamic credentials.

  2. Run the declarative imports.

  3. Export the HCP plan as JSON and run:

    python scripts/check-terraform-import-plan.py plan.json
    

    The first plan must be a no-op after import. The guard rejects updates, creates, deletes, replacements, and managed resource types outside the deploy role and inline policy.

  4. Apply the no-op import only after review.

  5. Change the environment root to adoption_complete=true in a reviewed code change, then review the controlled in-place role and policy update:

    python scripts/check-terraform-import-plan.py plan.json --allow-update
    
  6. Apply only when the plan contains updates to the imported deploy role and policy, with no create, delete, or replacement actions.

The reviewed adoption_complete=true change updates the ownership tag/description and narrows the dev role to the staging-style S3 bucket and application prefix. Read-only AWS APIs retain Resource = "*" only where AWS does not support resource-level permissions.

Pinned live identities

  • Dev: workspace shoc-backend-dev; EB environment shoc-backend-dev (e-hehnrqjjrt); .NET 8 AL2023 3.11.3; api.dev.seahaven.com.
  • Staging: workspace shoc-backend-staging; EB environment shoc-backend-staging (e-6c9m4vb62z); .NET 8 AL2023 3.11.3; api.staging.seahaven.com.

The environment roots are intentionally not general-purpose modules. Exact identifiers make accidental cross-environment reuse fail review and planning.

Safety invariants

  • Never reuse shoc-backend-tf-poc state.
  • Auto-apply remains off.
  • HCP apply roles have no IAM create/delete permissions and no service mutation permissions outside the exact imported deploy role.
  • Both managed resources have prevent_destroy.
  • Do not retire the CDK stack until the no-op import and controlled policy update have both succeeded.
  • Do not destroy the POC workload until dev and staging deployment smoke tests have stabilized.