mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-10-02 03:53:24 +00:00
Add import-only dev and staging state with least-privilege HCP authentication and plan safety guards.
170 lines
6 KiB
Markdown
170 lines
6 KiB
Markdown
# 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/`](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 in `shoc-backend-tf-poc`.
|
|
- `bootstrap/`: consolidated POC/dev/staging HCP role bootstrap in
|
|
`shoc-backend-bootstrap`.
|
|
- `live/dev/`: import-only dev deploy-role ownership in
|
|
`shoc-backend-dev`.
|
|
- `live/staging/`: import-only staging deploy-role ownership in
|
|
`shoc-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` (zone `Z07671212N75U4YLPWZR8`)
|
|
- 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` (OIDC `environment:tf-poc`)
|
|
- HCP org `seahaven`, project `seahaven-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`](live/README.md).
|
|
|
|
## Console setup (once)
|
|
|
|
1. In HCP Terraform, create project `seahaven-external-dev` if it does not exist.
|
|
2. 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
|
|
3. Create workspace `shoc-backend-tf-poc`:
|
|
- Same branch
|
|
- Working directory: `terraform`
|
|
- Execution mode: **Remote**
|
|
- Auto-apply: off
|
|
- Speculative plans: on
|
|
4. Do **not** use HCP "Quick setup AWS dynamic credentials".
|
|
|
|
## Discovery (before first workload apply)
|
|
|
|
```bash
|
|
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.io` OIDC exists (`create_tfc_oidc_provider=false` in bootstrap).
|
|
If the data source fails, set `create_tfc_oidc_provider=true`.
|
|
- `external-dev-execution-boundary` exists.
|
|
- `aws-elasticbeanstalk-service-role` exists.
|
|
- GitHub OIDC provider `token.actions.githubusercontent.com` exists.
|
|
|
|
## 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`.
|
|
|
|
```bash
|
|
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=true`
|
|
- `TFC_AWS_PLAN_ROLE_ARN` = output `hcp_plan_role_arn`
|
|
- `TFC_AWS_APPLY_ROLE_ARN` = output `hcp_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`):
|
|
|
|
```sql
|
|
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` → `dev`
|
|
- `staging` → `staging`
|
|
- `main` → `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:
|
|
|
|
```bash
|
|
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
|
|
|
|
1. Create `shoc-backend-dev` and `shoc-backend-staging` workspaces. Do not
|
|
reuse POC state.
|
|
2. Apply `bootstrap/` only after approval to create the four narrowly scoped
|
|
live HCP roles.
|
|
3. Follow the no-op import and controlled-update sequence in
|
|
[`live/README.md`](live/README.md).
|
|
4. Retire CDK deploy-role ownership only after both role imports are proven.
|
|
5. Destroy the POC workload last. Bootstrap state remains.
|
|
|
|
Do not apply this module as `environment=dev` without imports.
|
|
|
|
## Local CI equivalent
|
|
|
|
```bash
|
|
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
|
|
```
|