[199] Define each MMGIS environment in Terraform#211
Conversation
Translate the June recipes and the live environment's production-tested values into infrastructure/terraform/modules/mmgis-environment: ECS cluster, the admin Express Mode gateway service, per-environment admin/publish task definitions, RDS postgres (master user postgres, manage_master_user_password, deletion protection), two task security groups, two log groups, five Secrets Manager secret shells, a per-environment ECR repo, the shared asset bucket + OAC, the CloudFront distribution + VPC origin, task/exec/infra IAM roles, and the branch-scoped GitHub OIDC deploy role. The Express service does not expose its internal ALB ARN or on.aws endpoint as Terraform attributes, so the CloudFront front door is created in a documented second apply gated on two phase-2 inputs. No secret values or random_password anywhere: secret shells only.
Each root is a module call with commit-safe values, an S3 backend configured via -backend-config (per-environment state bucket, S3 native locking, no account-specific value committed), a terraform.tfvars.example and backend.hcl.example carrying only placeholders, and pass-through outputs (including the workflow variable values). Network ids, the RDS CA bundle, and the two-phase CloudFront inputs are uncommitted tfvars. Production exists as config; #195 bootstraps its state bucket and instantiates it.
…cs as apply-docs deploy-lean.yml now reads ADMIN_TASK_FAMILY/PUBLISH_TASK_FAMILY from repo variables, falling back to the legacy mmgis-admin/mmgis-publish names. Families are region-global, so per-environment names stop a production deploy from registering a revision development's publish-by-family flow would pick up. Rewrite infrastructure/README.md as apply-docs: prerequisites (existing VPC/subnets as inputs, per-environment state-bucket bootstrap, secret values set out-of-band with CLI examples referencing no real values), the two-phase plan/apply flow, and the workflow variables each environment needs. The runbook prose is gone; the hard-won operational notes (RDS postgres username, regional CA bundle, Express Mode not task-def-driven, dual DB secrets, CloudFront origin details, CI deploy-role facts) are kept and updated to the Terraform world. The recipe JSON files stay in place as provenance.
….11 floor, phase-2 ALB rule, secret recovery windows
Reviewer's guide to this diffA diff explainer for anyone reviewing cold. The PR is large (~2,400 lines) but highly structured: one Terraform module translated from the already-production-tested June recipes ( How to read this diff (2–3 minutes)
File group walkthroughWorkflow ( README rewrite. The old README was the hand-run runbook; the new one is apply-docs: state-bucket bootstrap, the two-phase apply, out-of-band secret values, the workflow-variables table (fed by Module naming and shape ( ECS ( Two-phase CloudFront ( Secret-shell discipline ( IAM ( Environment roots. Thin by design: only values that must not be committed (VPC/subnet ids, CA bundle, phase-2 inputs) are variables via git-ignored tfvars; everything safe to commit is inline in What to scrutinize
What's deliberately NOT here
|
…nvironments Carries the ADMIN_URL manually-maintained-by-design note (966b531) up the stack. Resolution: the workflow header keeps this branch's extended var list plus the note; 193's README sentence has no counterpart in this branch's rewritten README, so the note lands in the Workflow variables table row for ADMIN_URL instead.
…nvironments Carries the ADMIN_URL removal (d0e8306) up the stack: the variables-table row is gone, ADMIN_URL leaves the workflow_variables output map (it is no longer an Actions variable), and the terraform admin_url output stays as the authoritative — and only — place to read the admin URL.
The admin is internal tooling — the shipped product is the published dashboards, which serve independently of this stack — so production gets no availability/sizing headroom development doesn't have. The environments now differ only in deletion policy (final snapshot on destroy, secret recovery window) and the deploy branch.
Closes #199
Stacked on #210 (targets
feature/193-dev-deploy-ci; retarget todevelopmentafter #210 merges — theClosesfires then).Defines a complete MMGIS environment in Terraform, ending the hand-built/runbook era. One module, instantiated per environment (
development/production— full-word naming throughout), nothing shared between environments, each with its own state bucket.What's here:
infrastructure/terraform/modules/mmgis-environment/— cluster, Express Mode admin service (aws_ecs_express_gateway_service, AWS provider ≥ 6.22 with committed lock files), per-env task-definition families, RDS (managed master password, deletion protection,postgresusername enforced), security groups, log groups, secret shells (values never touch Terraform or its state), per-env ECR, CloudFront + VPC origin + OAC, task/exec/infra roles, and a branch-scoped OIDC deploy role carrying the four empirically-learned IAM/CLI corrections from Deploy the lean dev environment officially fromdevelopmentvia CI #193's first live runsenvironments/development/+environments/production/— thin roots with per-env S3 backends (production's bootstrap belongs to Add a protectedproductionbranch that deploys its own production environment #195)infrastructure/README.mdrewritten as apply-docs: two-phase apply (the provider doesn't export the ALB ARN / on.aws endpoint — phase 2 takes them as inputs, including the ALB security-group rule, so no hand-executed mutation remains), first-image-deploy ordering, secret CLI examples with no real valuesNot in this PR: applying it. The dev rebuild under
mmgis-development-*names happens after #210 merges and the e2e verification passes; production instantiation is #195.