Add import-only dev and staging state with least-privilege HCP authentication and plan safety guards. |
||
|---|---|---|
| .. | ||
| bootstrap | ||
| live | ||
| .terraform.lock.hcl | ||
| acm.tf | ||
| elastic_beanstalk.tf | ||
| iam_github_deploy.tf | ||
| iam_runtime.tf | ||
| locals.tf | ||
| outputs.tf | ||
| providers.tf | ||
| rds.tf | ||
| README.md | ||
| secrets.tf | ||
| security_groups.tf | ||
| terraform.tfvars.example | ||
| variables.tf | ||
| versions.tf | ||
Terraform deployment infrastructure
The root module remains the isolated tf-poc Elastic Beanstalk and SQL Server
stack in seahaven-external-dev (396287094661). It must never be reused for
dev or staging state.
Live adoption is deliberately smaller. live/ imports only the
existing GitHub Actions deploy roles and inline policies. All application,
environment, database, certificate, DNS, network, runtime IAM, and secret
resources remain external and are read only as inventory.
The Terraform roots are:
./: isolated POC workload inshoc-backend-tf-poc.bootstrap/: consolidated POC/dev/staging HCP role bootstrap inshoc-backend-bootstrap.live/dev/: import-only dev deploy-role ownership inshoc-backend-dev.live/staging/: import-only staging deploy-role ownership inshoc-backend-staging.
IAM lives in this repo, not org-baseline. App CD never runs a bootstrap root. Auto-apply stays off for every workspace.
The stabilized POC bootstrap deliberately leaves both POC HCP roles read only
and removes ViewOnlyAccess plus the broad workload-mutation inline policy.
The POC GitHub deploy role remains unchanged until a separately approved
narrowing or teardown. Future POC teardown runs directly under the approved
SSO administrator session, not the locked HCP apply role.
Locked names
- Hostname:
tf-poc.api.dev.seahaven.com(zoneZ07671212N75U4YLPWZR8) - EB application / environment:
shoc-backend-tf-poc - RDS identifier:
shoc-backend-tf-poc - Catalog:
shoc_tf_poc(create this database once after RDS is available) - Deploy role:
arn:aws:iam::396287094661:role/tf-managed/githubdeploy-shoc-backend-tf-poc - GitHub Environment:
tf-poc(OIDCenvironment:tf-poc) - HCP org
seahaven, projectseahaven-external-dev
HCP layout
All SHOC backend environments live in AWS account 396287094661 and HCP
The POC workspaces remain isolated until teardown. The live bootstrap owns
hcptf-shoc-backend-{dev,staging} and matching -plan roles. The live
environment workspaces own only their existing GitHub deploy role and inline
policy. See live/README.md.
Console setup (once)
- In HCP Terraform, create project
seahaven-external-devif it does not exist. - Create workspace
shoc-backend-bootstrap:- VCS later, or CLI-driven until the branch is pushed
- Working directory:
terraform/bootstrap - Execution mode: Local
- Auto-apply: off
- Create workspace
shoc-backend-tf-poc:- Same branch
- Working directory:
terraform - Execution mode: Remote
- Auto-apply: off
- Speculative plans: on
- Do not use HCP "Quick setup AWS dynamic credentials".
Discovery (before first workload apply)
export AWS_PROFILE=seahaven-external-dev
aws elasticbeanstalk describe-environments \
--environment-names shoc-backend-dev \
--region us-east-1 \
--query 'Environments[0].{Vpc:EndpointURL}'
aws elasticbeanstalk describe-configuration-settings \
--application-name shoc-backend \
--environment-name shoc-backend-dev \
--region us-east-1 \
--query "ConfigurationSettings[0].OptionSettings[?Namespace=='aws:ec2:vpc']"
Copy vpc-REPLACE_ME and subnet lists into a local terraform/terraform.tfvars
(gitignored). Confirm:
app.terraform.ioOIDC exists (create_tfc_oidc_provider=falsein bootstrap). If the data source fails, setcreate_tfc_oidc_provider=true.external-dev-execution-boundaryexists.aws-elasticbeanstalk-service-roleexists.- GitHub OIDC provider
token.actions.githubusercontent.comexists.
Bootstrap apply (Adam)
SSO AdministratorAccess in this account is subject to the external-dev SCP, so
both hcptf-* roles set permissions_boundary to
external-dev-execution-boundary.
export AWS_PROFILE=seahaven-external-dev
cd terraform/bootstrap
terraform login
terraform init
terraform apply
Then on workspace shoc-backend-tf-poc, set workspace-scoped env vars:
TFC_AWS_PROVIDER_AUTH=trueTFC_AWS_PLAN_ROLE_ARN= outputhcp_plan_role_arnTFC_AWS_APPLY_ROLE_ARN= outputhcp_apply_role_arn
Never put those in a project variable set. Set sendgrid_api_key as a
sensitive Terraform variable on that workspace when you want mail to work.
Workload apply
HCP Manual apply on shoc-backend-tf-poc. Confirm api.dev.seahaven.com still
serves live before and after.
After RDS is available, create the catalog once (SQL Server Express does not
accept db_name on aws_db_instance):
CREATE DATABASE [shoc_tf_poc];
Then first app deploy can run migrations into that catalog.
App deploy
GitHub Actions is the real CD path. .github/workflows/deploy.yml maps:
dev→devstaging→stagingmain→prod
The live roots import the roles already referenced by the dev and staging
GitHub Environment secrets. The role ARNs do not change during adoption.
The POC local fallback remains available until teardown:
export AWS_PROFILE=seahaven-external-dev
bash scripts/deploy-api-tf.sh
The script refuses live names (shoc-backend-dev, api.dev.seahaven.com).
After POC confirmation
- Create
shoc-backend-devandshoc-backend-stagingworkspaces. Do not reuse POC state. - Apply
bootstrap/only after approval to create the four narrowly scoped live HCP roles. - Follow the no-op import and controlled-update sequence in
live/README.md. - Retire CDK deploy-role ownership only after both role imports are proven.
- Destroy the POC workload last. Bootstrap state remains.
Do not apply this module as environment=dev without imports.
Local CI equivalent
terraform -chdir=terraform fmt -check -recursive
terraform -chdir=terraform init -backend=false && terraform -chdir=terraform validate
terraform -chdir=terraform/bootstrap init -backend=false && terraform -chdir=terraform/bootstrap validate
terraform -chdir=terraform/live/dev init -backend=false && terraform -chdir=terraform/live/dev validate
terraform -chdir=terraform/live/staging init -backend=false && terraform -chdir=terraform/live/staging validate