# Frontend Terraform (SPA CD) `terraform/live/dev` and `terraform/live/staging` in AWS account `396287094661`. HCP Terraform owns the bucket, CloudFront, DNS, and the GitHub deploy role. GitHub Actions owns content: `.github/workflows/deploy-web.yaml` syncs `dist/` to the bucket root and invalidates `/*`. Creating, formatting, initializing with `-backend=false`, and validating these files does not authorize an AWS, HCP Terraform, GitHub, or deployment mutation. Do not collapse these roots into one `terraform/` tree. Flattening retargets two live HCP working directories and is its own change. ## Fixed targets | | dev | staging | | ------------- | ------------------------------------ | ---------------------------------------- | | Site | `dev.seahaven.com` | `staging.seahaven.com` | | Bucket | `seahaven-shoc-frontend-dev` | `seahaven-shoc-frontend-staging` | | Distribution | `E2CWLM1AFB964P` | `E2JDVEZ6EGD49J` | | Deploy role | `githubdeploy-shoc-frontend-new-dev` | `githubdeploy-shoc-frontend-new-staging` | | HCP workspace | `shoc-frontend-new-dev` | `shoc-frontend-new-staging` | | Working dir | `terraform/live/dev` | `terraform/live/staging` | There is no prod CloudFront in this round. Do not create `shoc-frontend-new-prod`. ## Ownership `module.environment_owned` keeps the same addresses as the adopted HCP `shoc-frontend-new-dev` state. The SPA origin path is empty. The release pointer is forgotten (`removed { destroy = false }`), not destroyed. Deploy parameters live under `/shoc-frontend-new//deploy/{bucket,distribution-id}`. `githubdeploy` may List/Get/Put/Delete the bucket root, CreateInvalidation, and GetParameter on those two names. OIDC trust is `environment:` plus `job_workflow_ref` for `.github/workflows/deploy-web.yaml` at `refs/heads/main` and `refs/tags/v*`. `adoption_complete` is pinned in each live root. It is not a workspace variable. ## Local checks (no apply) ```bash terraform fmt -check -recursive terraform terraform -chdir=terraform/live/dev init -backend=false -lockfile=readonly terraform -chdir=terraform/live/dev validate terraform -chdir=terraform/live/staging init -backend=false -lockfile=readonly terraform -chdir=terraform/live/staging validate python3 scripts/test-terraform-import-plan-check.py python3 scripts/test_check_app_terraform_isolation.py bash scripts/test-verify-cloudfront-release.sh ``` PRs cannot mix `terraform/` with deployable application files. Workflow, docs, and gate-script changes may travel with either side. G13 is `python3 scripts/check_app_terraform_isolation.py` against the merge base of the PR, and against each queued PR (first-parent commit) on `merge_group`. `npm run test:terraform` and `npm run verify` wrap the same gates. They never create an HCP run or touch AWS. ## Workspaces Dev (`shoc-frontend-new-dev`) watches `main` with working directory `terraform/live/dev` and auto-apply on. Staging (`shoc-frontend-new-staging`) watches tag regex `^v[0-9]+\.[0-9]+\.[0-9]+-staging$` with working directory `terraform/live/staging` and auto-apply on. Merges to `main` do not apply staging. GitHub Environments `dev` and `staging` set `DEPLOY_ROLE_ARN` and allow `main` plus tag `v*`. Promote staging with `gh release create vX.Y.Z-staging --target main`.