# AWS Infrastructure ## IaC Strategy - **HCP Terraform** is the default for every new deployable, including a one-Lambda repo. GitHub Actions publishes application content. See [hcp-terraform.md](hcp-terraform.md), [terraform-project-layout.md](terraform-project-layout.md), and [cicd.md](cicd.md). - **CDK** for Bedrock Agents, Knowledge Bases, and other compositions SAM cannot express (ECS, VPCs). Do not start a new app workload on CDK in order to skip HCP. - **SAM** remains documented for stacks that already use it. Do not start a new deployable on SAM. - **Migrating stacks** from mgmt into `seahaven-prod` / `seahaven-dev` still use HCP Terraform (migrate-and-convert; do not convert in place in mgmt). Cut those over to the [hcp-terraform.md](hcp-terraform.md) seam (stub plus `ignore_changes`, GHA owns the zip) rather than keeping Terraform-packaged Lambda source. The org-baseline first-apply runbook still covers workspace create and `hcptf-*` roles. Reference implementation for a completed app cutover: `internal-portal`. - Every deployed resource should be managed by IaC - No manually-created Lambdas, roles, or other resources outside of IaC ## HCP Terraform VCS file triggers Canonical rules live in [hcp-terraform.md](hcp-terraform.md#vcs-file-triggers). New workspaces trigger on `terraform/**` only (dev) and on `vX.Y.Z` tags (prod). Do not add Lambda source trees to HCP triggers. GitHub Actions ships that content. Keep `file-triggers-enabled`. Do not turn file triggers off. `trigger-prefixes` are added to the working directory. `trigger-patterns` replace the working-directory filter and must include a glob for that directory. Remaining stacks where Terraform still packages Lambda code (mgmt migrations not yet on the seam) still list those source paths in triggers, as PLAT-183 required. New repos do not. `python3 scripts/check_hcp_workspace_triggers.py` in `seahaven-org-baseline` still flags an empty prefix/pattern pair when the Terraform tree references application source. After a repo adopts the seam it should no longer reference that source, and the checker should be quiet. Record the live prefixes or patterns in the app README next to the workspace name. ## Lambda Defaults These apply to every Lambda in every project. Verify, don't assume. | Setting | Value | |---|---| | Runtime | Python 3.12 or Node 24.x (`nodejs24.x`) | | Architecture | arm64 | | Log retention | 60 days (explicit in IaC template) | | Naming | kebab-case, matching the stack name prefix | Never rely on the CloudWatch default for log retention. Always set `RetentionInDays` explicitly in the template. ### Node runtime This is the canonical statement; [dev-environment.md](dev-environment.md#nodejs) and [cdk-project-layout.md](cdk-project-layout.md#lambda-defaults) defer to it. - **`nodejs24.x` is the standard.** Every new Node Lambda targets it, set explicitly in the IaC template. - **`nodejs22.x` is legacy only.** It is valid for functions that already run on it, and those move to 24.x before the AWS deprecation date of 2027-04-30. Do not start a new function on it. - **Never target `nodejs26.x`,** including once AWS ships it. Lambda applies runtime updates automatically, so a fresh major is only adopted after it has been generally available on Lambda for a full quarter, and only by a deliberate change to this page. Odd majors (25.x, 27.x) never become Lambda runtimes at all. ## CDK Version Policy Pin `aws-cdk-lib` to an exact version (no `^`, `~`, or `>=`) and let Dependabot keep it current. There is no static "blessed version" — the org standard is the latest release that passes the gates below. Do not add blanket `dependabot.yml` ignore entries for `aws-cdk-lib`; that is how pins rot into carrying known vulnerabilities. Why exact + automated: the exact pin plus the lockfile gives reproducible builds; weekly Dependabot version updates keep the pin moving; CI (`npm ci` + `cdk synth`) and the dependency-review check reject a bad release at the PR. A release with broken bundled-dep metadata (e.g. 2.254.0) fails `npm ci` on its own bump PR; a release bundling a vulnerable transitive dep fails dependency review. Either way, a bad release never merges — the gates do the vetting, not a frozen number in this document. aws-cdk-lib bundles transitive dependencies (`inBundle: true`) that npm `overrides` cannot patch. When a bundled dep has a vulnerability, the only fix is advancing to a release that bundles the patched version — treat the alert as a prompt to merge the next Dependabot bump, never as something to dismiss indefinitely. If a specific release is known-bad, ignore that version only (`ignore: - dependency-name: aws-cdk-lib, versions: ["2.254.0"]`) with a comment explaining why, and remove the entry once a fixed release ships. When upgrading, verify on a branch first: 1. Update `package.json` to the new version 2. Run `rm -rf node_modules package-lock.json && npm install` 3. Run `npm ci` — if it fails, the version is not safe 4. Run `npx cdk synth` — if it fails, the version is not safe ## CloudFormation Outputs Every stack should export: - Function ARNs - Any externally-consumable URLs (API Gateway endpoints, etc.) ## S3 - Every non-CloudFormation bucket must have `Purpose` and `ManagedBy` tags - Define lifecycle policies in the IaC template - Use Glacier Deep Archive for archival data ## README Every repo must have a README that accurately describes: - Project architecture - Lambdas and services - Data flow - Configuration requirements Update the README in the same commit where functionality changes. If a README is missing or outdated when you start working on a project, fix it as part of the current work.