mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-03 19:03:15 +00:00
136 lines
5.6 KiB
Markdown
136 lines
5.6 KiB
Markdown
# Frontend infrastructure and migration rehearsal
|
|
|
|
This CDK app describes the existing Sea Haven SHOC SPA hosting and an isolated,
|
|
production-shaped Terraform adoption rehearsal. It performs no content upload.
|
|
Content-only deployment is handled by `scripts/deploy-web.sh`.
|
|
|
|
## Existing environments
|
|
|
|
Normal synthesis remains unchanged when the adoption flag is off:
|
|
|
|
- private, versioned S3 bucket with CDK auto-delete cleanup
|
|
- CloudFront distribution and origin access control
|
|
- viewer-request function that rewrites extensionless SPA routes
|
|
- optional Route 53 A and AAAA aliases
|
|
- GitHub Actions OIDC deploy role
|
|
|
|
Dev remains the default context in `cdk.json`. Staging uses explicit context
|
|
arguments. During migration, both content workflows are manual-only and use
|
|
fixed environment configuration rather than discovering deployment targets
|
|
from CloudFormation.
|
|
|
|
## Terraform POC
|
|
|
|
The POC is isolated in account `396287094661`, region `us-east-1`, and is
|
|
created only with `-c tfPoc=true` plus an explicit `tfPocPhase`. It uses three
|
|
ownership scopes:
|
|
|
|
1. `shoc-frontend-tf-poc-shared`: a dedicated public hosted zone for
|
|
`frontend-tf-poc.seahaven.com`.
|
|
2. `shoc-frontend-tf-poc-certificate`: the DNS-validated ACM certificate.
|
|
3. `shoc-frontend-tf-poc`: the private versioned bucket, CloudFront OAC,
|
|
distribution, SPA function, A/AAAA aliases, and GitHub OIDC content deploy
|
|
role.
|
|
|
|
Fixed application values:
|
|
|
|
- bucket: `seahaven-shoc-frontend-tf-poc`
|
|
- role: `githubdeploy-shoc-frontend-new-tf-poc`
|
|
- GitHub environment: `tf-poc`
|
|
- site: `https://frontend-tf-poc.seahaven.com`
|
|
- API: `https://api.tf-poc.seahaven.com/api`
|
|
|
|
The shared stack is intentionally staged. The zone must exist and be delegated
|
|
before ACM can validate a certificate inside it:
|
|
|
|
```bash
|
|
cd infra/cdk
|
|
npm ci
|
|
npm test
|
|
npm run synth:tf-poc-zone
|
|
npm run synth:tf-poc-environment
|
|
```
|
|
|
|
After approval, deploy only `shoc-frontend-tf-poc-shared` with
|
|
`tfPocPhase=zone`. Its outputs provide the child name servers. Create the
|
|
parent NS record as a separate approved change and verify public delegation.
|
|
Only then use `tfPocPhase=environment` to deploy the separate certificate and
|
|
site stacks. The zone stack never contains the certificate, so re-running the
|
|
zone phase cannot remove a certificate created by the environment phase.
|
|
Omitting `tfPocPhase` fails closed.
|
|
|
|
The stacks output the hosted zone ID, certificate ARN, delegation evidence,
|
|
workspace tag, boundary ARN, and import IDs for the bucket, bucket policy,
|
|
distribution, OAC, SPA function, A/AAAA records, deploy role, and inline role
|
|
policy. They also emit the generated OAC name/description, deterministic origin
|
|
ID, and inline policy name required by the tf-poc Terraform configuration.
|
|
|
|
## Adoption retention
|
|
|
|
`-c retainForTerraformAdoption=true` is deliberately opt-in. Keep it enabled
|
|
from the reviewed retention deployment through CloudFormation ownership
|
|
detachment.
|
|
|
|
The emitted template applies both `DeletionPolicy: Retain` and
|
|
`UpdateReplacePolicy: Retain` to:
|
|
|
|
- site bucket and bucket policy
|
|
- distribution, OAC, and SPA rewrite function
|
|
- A and AAAA records
|
|
- GitHub deploy role and its inline policy
|
|
- `SiteBucket/AutoDeleteObjectsCustomResource`
|
|
|
|
The bucket remains configured with `autoDeleteObjects: true`. The emitted
|
|
bucket and its matching custom resource are both retained, so deleting the
|
|
stack cannot invoke that custom resource to empty the versioned bucket.
|
|
Generated provider Lambda resources, provider IAM resources, provider logs,
|
|
and CDK metadata are intentionally excluded. Template tests enforce this exact
|
|
boundary.
|
|
|
|
In adoption mode, the deploy role also receives:
|
|
|
|
- tag `HcpTerraformWorkspace=shoc-frontend-new-{env}`
|
|
- permissions boundary
|
|
`arn:aws:iam::<account>:policy/shoc-frontend-new-{env}-deploy-boundary`
|
|
- exact `StringEquals` OIDC subject matching; for dev this narrows the current
|
|
no-wildcard `StringLike` subject before Terraform import
|
|
|
|
These changes are absent when the flag is off.
|
|
|
|
## Content deployment safeguards
|
|
|
|
`scripts/deploy-web.sh` requires explicit target and expectation variables:
|
|
|
|
- `SITE_BUCKET` and matching `EXPECTED_SITE_BUCKET`
|
|
- `CLOUDFRONT_DISTRIBUTION_ID`
|
|
- `SITE_URL`
|
|
- `VITE_API_URL` and matching `EXPECTED_API_URL`
|
|
- `DEPLOY_RELEASE_ID` or `GITHUB_SHA`
|
|
- optional comma-separated `FORBIDDEN_API_URLS`
|
|
- optional `API_SMOKE_URL` and `API_CORS_ORIGIN`
|
|
|
|
The script verifies bucket versioning, builds the app, publishes immutable
|
|
assets and a no-cache index, records a release manifest, invalidates and waits,
|
|
then checks `/`, `/login`, an extensionless route, asset references, API URLs,
|
|
and cache headers. Optional API preflight checks verify CORS.
|
|
|
|
If verification fails after publishing the index, the previous index version
|
|
is restored and invalidated. Pruning starts only after successful remote
|
|
verification. Current versions needed by the latest two release manifests are
|
|
kept; unreferenced object versions are deleted.
|
|
|
|
## Manual workflows
|
|
|
|
- `.github/workflows/deploy.yml`: dev content deployment
|
|
- `.github/workflows/deploy-staging.yml`: staging content deployment
|
|
- `.github/workflows/deploy-tf-poc.yml`: isolated POC content deployment
|
|
|
|
All are `workflow_dispatch` only. Staging and tf-poc retain their GitHub
|
|
environment protection and exact environment-scoped OIDC trust. Each dev and
|
|
staging distribution ID is pinned in its workflow. The tf-poc environment
|
|
must define its generated `CLOUDFRONT_DISTRIBUTION_ID` as a protected variable.
|
|
Each workflow pins its environment's Swagger URL for API CORS/preflight checks.
|
|
|
|
Infrastructure creation, parent-zone delegation, Terraform imports, and
|
|
ownership detachment remain separate administrator actions. None of these
|
|
workflows performs them.
|