Skip to content

Repo update july 26 - #295

Open
awshans wants to merge 5 commits into
aws-ia:mainfrom
awshans:repo-update-july-26
Open

Repo update july 26#295
awshans wants to merge 5 commits into
aws-ia:mainfrom
awshans:repo-update-july-26

Conversation

@awshans

@awshans awshans commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Description

Broad modernization of the ECS Blueprints repo across Terraform, CDK, and the sample applications, in five themes:

  • Self-contained terraform/patterns/ catalog — each blueprint now creates and destroys its own VPC, cluster, and workload in a single terraform apply, with no core-infra prerequisite. Added/converted: lb-service, backend-service, express-mode, native-deployment, managed-instances, service-connect, graviton, ipv6-only, prometheus, queue-processing, sqs-dynamic-target-tracking, vpc-endpoints. core-infra and the fargate-examples/* are retained as a shared-cluster topology reference and convert incrementally. Adds a "Which example should I start with?" decision table.

  • Least-privilege IAM in the CDK examples — replaced broad managed policies (AmazonS3FullAccess, AmazonSageMakerFullAccess) and resources=["*"] grants with resource-scoped statements; the CI/CD construct uses a dedicated immutable ECS deploy role; Bedrock KB and OpenSearch Serverless moved off public network access to VPC-endpoint / scoped data-access policies; S3 buckets get BLOCK_ALL + enforce_ssl.

  • CDK layout and API modernization — shared constructs moved to cdk/components/; each example owns its lib/ stacks; upgraded to aws-cdk-lib 2.262.1; migrated deprecated APIs (iteratoritem_processor, definitiondefinition_body, container_insightscontainer_insights_v2, EcsOptimizedImage→SSM AL2023 AMI) replaced distutils.strtobool with a local components/config.py helper; restored/added unit tests; added TypeScript variants for lb_service and data_pipeline.

  • EC2 examples and CI/CD topologies — modernized distributed-training, vLLM, Triton, and Inferentia examples with pinned provider versions; added external-state and IaC pipeline CI/CD examples; renamed variable.tfvariables.tf.

  • Application correctness and container security — proper error handling, malformed-message → DLQ redrive, SIGTERM graceful shutdown, UUID-based FIFO dedup, and IMDSv2 token acquisition in the sample apps; Dockerfiles now run as non-root, pin base images (Node 22, Python 3.12), use npm ci and health checks, and ship .dockerignore files.

Repo infrastructure: new GitHub Actions ci.yaml (terraform / cdk-python / cdk-typescript / applications / docker / documentation), an opt-in deploy-test.yaml (gated real-account deploy test), a rewritten pre-commit.yaml with pinned, checksum-verified tools, and new docs (authentication.md, repository-structure.md,terraform-v7-migration.md, example-contract.md).

Motivation and Context

Most examples previously required deploying core-infra before anything else would run, which broke the "clone and apply once" experience and made blueprints hard to evaluate in isolation. Several also used overly broad IAM, outdated base images and CDK APIs, public network access on data stores, and application code with unhandled error paths. This change makes each pattern independently deployable, brings IAM to least privilege, hardens the sample containers, and adds CI so all three IaC surfaces (Terraform, CDK Python, CDK TypeScript) and the applications stay validated on every PR.

How Has This Been Tested?

  • I have tested and validated these changes using one or more of the provided examples/* projects
  • [x ] I have executed pre-commit run -a on my pull request

awshans added 5 commits August 3, 2026 11:08
- container-queue-proc: per-message error handling replaces the poison-message
  crash loop; malformed messages go to the DLQ instead of redelivering forever
- lambda-function-queue-trigger: chunk run_task into batches of 10 (API limit),
  count tasks by task-definition family, paginate, validate config
- ecs-target-setter: cluster/service names from environment (matches the
  Terraform that deploys it), region from session, zero-division guards
- ecsdemo-queue-proc: validate message duration (None/negative/NaN/cap), handle
  SIGTERM gracefully, region from environment
- message-producer: UUID dedup IDs (16-bit random silently dropped messages)
- data-pipeline-task: initialize context before try, reliable failure callback,
  nonzero exit on failure
- ecsdemo-cicd: gunicorn (non-root) replaces the Flask debug server; backend
  call gets a short timeout so an outage can't pin the worker pool;
  create-configs.py handles revision-less ARNs and emits .json (not .json.json)
- nodejs-demoapp: session secret from env, stack traces gated to development,
  COGNITO env-var typo, lazy msal import, non-root Docker + HEALTHCHECK,
  cgroup-v2-aware memory metrics
- ecsdemo-nodejs: node:22 base (was EOL ubuntu:18.04/Node 8), remove vulnerable
  unused deps (ip, internal-ip), IMDSv2 in startup scripts, placeholder IDs in
  ecs-params.yml
- All Dockerfiles: current non-EOL pinned bases, non-root users, exec-form
  entrypoints; add .dockerignore files
- tests/: 31 stdlib-only unit tests covering the fixed behaviors
Modules:
- codebuild-iac rewritten: scoped log/S3/SSM resources, per-service PassRole
  with iam:PassedToService conditions, validation rejects iam:/sts: actions in
  deployment statements (was CreateRole/AttachRolePolicy/PassRole on *)
- codepipeline/codebuild: unscoped PassRole replaced with opt-in scoped
  pass_role_arns; ECS actions parameterized via ecs_resource_arns
- codedeploy: deployment_config_name and action_on_timeout variables, clear
  precondition when no service role is available

CI/CD examples:
- S3 native state locking (use_lockfile, Terraform >= 1.11)
- external-state-bucket hardened (public access block, SSE, TLS-only policy)
- iac-pipeline roles carry only the actions their stages need, including the
  Route 53 actions Cloud Map namespace management requires
- blue/green target-group semantics corrected (blue = initial production)
- QA modules repaired to validate when uncommented; walkthrough README commands
  match the actual variables; typos fixed (application, notifications,
  appspec.json double extension - fixed in lockstep with create-configs.py)

EC2 examples:
- AL2023 ECS AMIs everywhere (AL2 is past EOL), IMDSv2 required, EBS encrypted
- Internet-facing inference ALBs made internal with VPC-scoped security groups;
  SYS_ADMIN dropped (IPC_LOCK retained for Neuron)
- ReadOnlyAccess task roles replaced with bucket-scoped policies
- Ray control-plane SGs narrowed from 10.0.0.0/8 to the VPC CIDR
- Dead Ray image tags replaced with published ones
- Cross-example name collisions eliminated (clusters, placement groups, IAM
  roles, Cloud Map services - worker discovery now derives from the resource)
- Boot-time docker builds gated so ECS can't place tasks before the image exists
- Wait scripts take region as a parameter, use stable triggers, and fail with
  clear capacity errors instead of index-out-of-range
- terraform-aws-modules/ecs 7.5.0 + AWS provider ~> 6.56 across all roots
- codestar_cicd_construct: secrets/S3/ECR wildcards and PassRole/AssumeRole on
  * replaced with a dedicated scoped deploy-action role (task-definition actions
  stay on * - they support no resource-level permissions)
- data_pipeline: broad role policies replaced with CDK grants; $.foldername
  passed as a JsonPath instead of a literal (Python and TypeScript); error
  catches route to a real broadcast-error state; TS RUN_JOB -> task-token
- GenAI stacks: internal ALBs, bedrock/aoss/sagemaker scoped to exact ARNs,
  SageMaker roles keep CloudWatch Logs/metrics, JumpStart toggle no longer
  crashes, sagemaker import made lazy
- OpenSearch/Bedrock: VPC-endpoint network policy for the vector stack;
  RAGBucket hardened; collection endpoint stays reachable for the index
  custom resource (documented)
- Fixed across examples: sd_namespace ARN-in-ID setter (7 files), distutils
  removal via components/config.py parse_bool, namespace lookups raise clear
  errors instead of IndexError, event_bridge alarm sees both stop codes and
  the service is private, Streamlit page bugs, AL2023 for the optional EC2 path
- One dependency set: aws-cdk-lib 2.262.1, pytest 8.x; test suite restored from
  broken imports to 16 passing tests
- Layout: other_stack/ dissolved into its consumers' lib/ dirs;
  examples/components/ -> cdk/components/ (examples/ lists only startable apps)
- New: express_mode example (Express Gateway service, quick start + custom task
  definition variant) and a TypeScript lb_service example - the canonical TS
  starting point (own VPC/cluster/ALB, jest tests)
terraform/patterns/ is now the primary catalog: 13 self-contained blueprints
that create their own VPC and cluster, deploy with one apply, and destroy
cleanly. Every deployable pattern was applied, smoke-tested, and destroyed in a
sandbox account.

New feature patterns (last 12 months of ECS launches):
- native-deployment: rolling/blue-green/linear/canary with lifecycle hooks,
  alarms, circuit breaker, and a pause/continue + Action Logs workflow
- managed-instances: Spot/on-demand, scale-in delay, instance requirements, a
  Managed Daemon; plan-gates on EBS encryption-by-default with the fix command
- service-connect: three services with TLS (optional PCA), Envoy access logs,
  optional cross-account namespace
- express-mode: image-to-HTTPS-endpoint quick start plus a custom task
  definition variant with FireLens (public subnets so the managed endpoint is
  internet-facing)
- ipv6-only: IPv6-native tasks, dual-stack ALB without public IPv4; the
  account-wide dualStackIPv6 setting is a documented one-line prerequisite so
  apply AND destroy work out of the box

Converted from shared-cluster examples (README stubs left at the old paths so
existing links keep resolving):
- lb-service, backend-service, graviton, sqs-dynamic-target-tracking,
  queue-processing, prometheus (creates its own Managed Prometheus workspace),
  vpc-endpoints (no NAT/IGW - tasks pull through an ECR pull-through cache with
  zero internet egress, proven via wait_for_steady_state)

fargate-examples/ keeps core-infra as an intentional shared-cluster topology
reference plus backstage, whose real prerequisites are now documented honestly.
CI/CD-bundling patterns (graviton, sqs, queue-processing) are labeled with
their GitHub fork + token prerequisite instead of claiming one-command deploys.
- .github/workflows/ci.yaml: terraform validate, CDK tests + synth (Python and
  TypeScript matrix), application tests, all Docker builds, and a README
  contract check on every PR; actions pinned to commit SHAs
- .github/workflows/deploy-test.yaml + scripts/ci/deploy-test.sh: scheduled
  apply -> HTTP smoke test -> guaranteed destroy of representative patterns in
  a sandbox account via OIDC (inert until the role/environment are configured)
- scripts/ci/: terraform, cdk-python, applications, docs runners
- README: 'Which example should I start with?' decision table mapping 22 use
  cases to examples with IaC availability and self-containment, honest CDK
  scope note, current auth guidance (no Cloud9/static keys)
- docs/: repository-structure.md (target layout and rules for new content),
  example-contract.md (enforced README sections), authentication.md,
  terraform-v7-migration.md (tested v5 -> v7 module migration path)
- pre-commit workflow refreshed: SHA-pinned actions, current terraform-docs and
  tflint with checksum verification
@awshans
awshans requested a review from a team as a code owner August 3, 2026 18:13
@awshans
awshans force-pushed the repo-update-july-26 branch from 47fa7db to ddb5ba7 Compare August 3, 2026 19:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants