Reviewer flagged two security-relevant items and two operational bugs on the external-DB + Terraform module merge. 1. Terraform: `enable_execute_command = true` was hardcoded on the app and embedder services. Production attack surface (anyone with `ecs:ExecuteCommand` on the service gets a container shell) AND non-functional today since the task roles have no `ssmmessages:*` permission. Added a new `enable_execute_command` boolean input variable defaulting to `false`; when flipped on, the SSM messages policy is conditionally attached to both task roles so the feature actually works. README's variable description tells operators to flip on for incidents, off afterward. 2. Terraform: `secret_arns` output was not marked `sensitive`. The ARNs themselves aren't secrets, but the embedded secret names print to `terraform apply` stdout and CI logs. Marked sensitive on both the module output and the example output. Operators wanting the values can still `terraform output -json secret_arns`. 3. Terraform: embedder task definition was missing `HOST=0.0.0.0` and `PORT=8080`. Fargate awsvpc tasks each get their own ENI; default Node HTTP servers bind 127.0.0.1, which would make every app→embedder Service Connect call time out. Added both vars to `embedder_environment`. Also added `NEXT_TELEMETRY_DISABLED=1` to `app_environment` per the spec's hardening checklist. 4. Compose: docker-compose.external-db.yml uses the `!override` YAML tag, which requires Docker Compose >= 2.24.0. Silently ignored on older Compose, causing the `db` dependency to survive the merge and startup to fail. Documented the minimum version in the override file's header AND in the main README prerequisites with a deep link to the External Postgres section. terraform fmt + validate (module + examples/basic) both clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Basic example — shared-memory on AWS Fargate
Minimal invocation of ../../. Fill in your real IDs and run.
Prereqs
Before you terraform apply, you need (see the module README
for the long version):
- A VPC with two public + two private subnets
- An RDS Postgres ≥ 15.5 instance with
pgvector,pg_trgm,pgcryptoavailable (or creatable by the migrator on first run) - An ACM certificate in the same region as the ALB, covering
domain_name - ECR repos populated with images for
apps/webandapps/embedder - OIDC clients registered (web confidential + MCP public/PKCE)
Configure
-
Open
main.tfand replace the placeholdervpc-…/subnet-…/arn:aws:acm:…/ image URIs with your real values. -
Create
terraform.tfvarswith the sensitive inputs and chmod it:umask 077 cat > terraform.tfvars <<EOF database_url = "postgres://memory:CHANGEME@my-rds-host.us-east-1.rds.amazonaws.com:5432/memory" oidc_client_id_web = "abc123…" oidc_client_secret_web = "secretvalue" oidc_client_id_mcp = "def456…" nextauth_secret = "$(openssl rand -base64 32)" cli_token_secret = "$(openssl rand -base64 32)" EOF chmod 600 terraform.tfvars
Apply
terraform init
terraform plan -out plan.out
terraform apply plan.out
Post-apply
Open the module README for the migrator
aws ecs run-task invocation and the DNS setup.
The shortcut, using outputs from this directory:
CLUSTER=$(terraform output -raw ecs_cluster_name)
FAMILY=$(terraform output -raw migrator_task_definition_family)
SG=$(terraform output -raw migrator_security_group_id)
SUBNETS=$(terraform output -json private_subnet_ids | jq -r 'join(",")')
aws ecs run-task \
--cluster "$CLUSTER" \
--task-definition "$FAMILY" \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[$SUBNETS],securityGroups=[$SG],assignPublicIp=DISABLED}"