# 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. Live cutover waits for an explicit greenlight. Do not collapse these roots into one `terraform/` tree in this PR. 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 PR base. `npm run test:terraform` and `npm run verify` wrap the same gates. They never create an HCP run or touch AWS. ## Cutover (greenlight only) 1. Keep HCP working directories `terraform/live/dev` and `terraform/live/staging`. Dev VCS branch `main`. Staging tag regex `^v[0-9]+\.[0-9]+\.[0-9]+-staging$`. 2. Auto-apply off. Apply the origin-path move for **dev** before any `--delete` root sync. 3. Create GitHub Environment `dev` (staging already exists). Set `DEPLOY_ROLE_ARN` on each. 4. Enable `deploy-web.yaml`. Then delete leftover `deploy.yml` / `deploy-staging.yml` and repo `TF_API_TOKEN`, `TERRAFORM_CONTENT_CD_ENABLED`, and `AWS_DEPLOY_ROLE_ARN`.