terraform-aws-modules/terraform-aws-ecs examples/fargate (tag v7.6.0), its Fargate flagship example

Source: https://github.com/terraform-aws-modules/terraform-aws-ecs.git at v7.6.0.

Set: core. Lane: terraform-popular.

Why it is in the core set: a most-downloaded terraform-aws-modules example, pinned by tag; the shape most people deploy

Not clear yet.

StageVerdictDetail
Cold deploypass62 resources, once for real
Migratepass46 of 62 stamped
Replan from nothingpassgenuinely empty replan (“No changes. Your infrastructure matches the configuration.”) - #371, #378, #372, #110, #395 and #376 all fixed and stay fixed; the standalone task definition’s essential/mountPoints[].readOnly wall is gone (lex00/floci#131, published and repinned this unit) and essential defaulting to true was never an independent wall on its own (this unit’s own re-measurement). #395/#376: choudoufu keeps no persisted state, so every plan re-derives PriorState through ImportResourceState’s bare stub; internal/live/projection/build.go’s configuredAttrsSeed generalizes the tags-only import-stub seed (issue #287 item 8) to every Required-or-Optional-non-Computed attribute (fixing #376’s track_latest/skip_destroy directly), and internal/live/projection/residue.go’s residueConfigSourced widening of classifyResidue plus the new builder.residueSeedFor pre-read seed close #395’s managed-reference case (task_definition = aws_ecs_task_definition.this[0].arn) that configuredAttrsSeed’s static evaluator alone could not reach. Identities confirmed by value against the AWS CLI: $CLUSTER_ARN, $TD_SVC_ARN, $TD_STANDALONE_ARN, and #368’s scalable target $GOT_TARGET_RID.
No-op applypassgenuine no-op (0 added, 0 changed, 0 destroyed); 46 tofu-estate-tagged objects before, 46 after, no state file either time
Drift and reconvergepassone object tampered (VPC’s Name tag), plan proposed fixing exactly module.vpc.aws_vpc.this[0], apply changed 1 and the Name tag reconverged
Renamepassmoved block: module.alb renamed with zero churn (0 add, 9 change, 0 destroy), marker rewritten in place; live-mv: aws_service_discovery_http_namespace.this renamed with zero churn, marker rewritten in place; stock oracle over the same two-object rename on cold_deploy’s own state also shows zero churn (0 add, 0 change, 0 destroy); both live ids unchanged, read via the AWS CLI
Remove a blockpasschoudoufu: deleting module.ecs_task_definition’s block proposed exactly 8 destroys (0 add, 0 change, 8 destroy), address-for-address identical to stock’s oracle on cold_deploy’s own state; applied cleanly (0 added, 0 changed, 8 destroyed); the standalone task definition family (ex-fargate-standalone) genuinely has 0 active revisions afterward, read via the AWS CLI, not choudoufu’s own report; classifyOrphans did not withhold any destroy because no other module.ecs_task_definition block is declared anywhere in this config; the next plan is empty
Change count (planned)not run
Replace with create_before_destroynot run
Crash between create and destroy (planned)not run
Teardown (planned)not run
Plan, review, apply (planned)not run
Greenfield applypass62 resources from nothing, cluster marker verified via the AWS CLI, 60 of 62 records in the local record store (#364 A2; the 2 aws_ecs_task_definition instances are excluded by a numeric-wire-identity-component gap in internal/live/identity/located.go’s LocatedIdentityPlanFor, documented in this script and not fixed here - their markers and plans are unaffected), replan empty, stock oracle in its own namespace matches structurally on cluster/service/standalone-task-definition/CloudMap-namespace/ALB/VPC
Strict profile (planned)not run

Last run at commit 4ba0356d2c on 2026-08-25T17:44:48Z, exit code 0.

RE-CROSSED FOR REAL 2026-08-21 at dbc5ebf575 (GitHub issue #346’s fix), twice, the second time instrumented to capture live-plan’s raw output. STAGES UNCHANGED at 2 of 5, and #346’s fix does not reach this estate either. Stage 1: ‘Apply complete! Resources: 62 added, 0 changed, 0 destroyed’, cluster confirmed carrying no tofu-address beforehand. Stage 2: ‘46 of 62 eligible (28 VERIFIED + 18 DRIFTED); 16 skipped’; ‘46 stamped, 1 recorded (time_sleep.this[0]), 0 failed, 15 skipped’; both markers confirmed by direct aws ecs describe-* calls against floci rather than through choudoufu’s own report (cluster/ex-fargate = module.ecs_cluster.aws_ecs_cluster.this:0, service/ex-fargate/ex-fargate = module.ecs_service.aws_ecs_service.this:0). Stage 3 fails on exactly 8 diagnostics, the same 8 as before, verified two ways (grep -c ‘^Error:’ over the raw output, and the script’s own hard count assertions): 1 ‘Module output not supported in static context’ on main.tf:68 (cluster_arn = module.ecs_cluster.arn), 1 ‘Unable to compute static value’ on modules/service/main.tf:1565 (aws_appautoscaling_target.this[0].resource_id), and 6 ‘Unresolvable identity’ cascading from it onto aws_appautoscaling_policy.this[‘cpu’] and [‘memory’]. Why the fix misses it: the same value-shaped module-CALL-argument route as corpus-rds-complete-postgres, PLUS a transform the part-shaped route could not express even if it reached - local.cluster_name = element(split(’/’, var.cluster_arn), 1), a function applied to the deferred value. identity.Formula holds literals and ParentRefs and has no way to say ‘split this parent attribute and take element 1’. That is a mechanism this repository does not have, not a gap in #346’s fix. A ‘Provider version does not match the admission evidence version’ warning (6.61.0 resolved against 6.59.0 admission evidence) also prints; the script’s own header calls it a caution, not a failure. PRIOR HISTORY BELOW. Landed dd83121592 (2026-08-18), 62 resources: ECS cluster (Container Insights, FARGATE/FARGATE_SPOT split), a BLUE_GREEN service behind an ALB, ECS Exec, ECS Service Connect, a two-container task definition plus a standalone second one, a CloudMap namespace, nested ALB/VPC modules. cold_deploy and migrate genuinely pass (43 of 62 stamped: 26 VERIFIED + 17 DRIFTED; 19 skipped - 16 untaggable by design, 3 blocked by #305). test_plan blocked by 4 sites: #305’s familiar default_* trio (3 sites) and a NEW one, filed as #308: the child-module for_each keyset prover (internal/live/identity/foreach_keyset.go) has no case for a for-comprehension (for k, v in var.container_definitions : k => v if …) and doesn’t chase a bare var.X for_each source across a module-call boundary to the literal object constructor at the caller, whose keys are actually static even though one unrelated attribute value inside the map is dynamic - resolve.go’s resource-level forEachOverComprehension already does the equivalent per-entry evaluation the module-call prover lacks. Two real floci gaps found and filed but not fixed, both sized as real modeling work rather than quick patches: lex00/floci#59 (CreateCluster silently drops settings/Container Insights, default_capacity_provider_strategy never serialized back) and lex00/floci#60 (CreateService/DescribeServices drop scheduling_strategy, enable_ecs_managed_tags, enable_execute_command, health_check_grace_period_seconds, deployment_controller, blue-green load_balancer.advanced_configuration, service_connect_configuration entirely - scheduling_strategy’s omission in particular forces the AWS provider to propose destroy-and-recreate on every plan after creation, a real non-idempotency bug independent of choudoufu). Neither floci gap blocks this crossing’s own outcome since test_plan already refuses earlier, upstream of any ECS-field diff. Follow-up pass 2026-08-18 (#313 cross-check, 0a94070b16/3ff22c5be6): the committed run.sh still asserted pre-#305 counts (43/62 eligible) and failed before ever reaching stage 3; updated to the real current numbers (46/62 eligible, #305’s default_* trio now fully resolved here) and re-verified against real floci twice plus a BREAK=1 negative control, all read from the script’s own printed lines. test_plan’s sole remaining blocker is confirmed #308 alone - #313’s diagnostic does not appear anywhere in the output. Mechanism: this estate’s vpc submodule expands subnets via count over a statically-known length, never a for_each keyed on the AZ name values, so #313 structurally can’t reach it. Commented on #313 and #308. #308 fixed and merged 2026-08-18 (a9ac6d06e7/b2bb59585d, generic: a *hclsyntax.ForExpr case plus a cross-module-call var/local chase in internal/live/identity/foreach_keyset.go, reaching every module-call for_each proof, not just this estate) - re-run confirms 0 occurrences of #308’s diagnostic (was 1), but test_plan is still blocked: #308 firing first had been masking two more causes in the same live-plan output all along. Follow-up pass 2026-08-18 (e74c7d5869/07c7317ab6) re-staled run.sh’s stage-3 assertions and header to the real current picture, verified across three separate real live-plan runs (stable counts each time) plus a BREAK=1 negative control: 236 total diagnostics, three distinct root causes, not one. Root cause A (#313’s canonical shape, 48 sites): data.aws_availability_zones.available feeding local.azs into module “vpc”’s azs argument. Root cause B (also #313’s family via a module output, 1 site): module.ecs_cluster.arn passed into module “ecs_service” as cluster_arn, “Module output not supported in static context”. Both A and B are #313’s already-ruled maintainer-level architecture question (live-plan never calls a provider during plan), not fixed here. Root cause C (NOT #313 - a distinct, newly-found, likely-fixable gap #308’s own fix exposed, 4 sites): each.value.enable_cloudwatch_logging/create_cloudwatch_log_group inside module.container_definition, both literal booleans in the caller’s own object literal but refused because each.value is treated as one opaque blob instead of projected to the referenced field - filed as #315, not attempted. These cascade to 177 “Unable to compute static value” and 6 “Unresolvable identity” sites (traced: aws_appautoscaling_policy reads aws_appautoscaling_target’s resource_id, itself one of C’s failures). Re-verified 2026-08-19 (be6b1096ba/b7bbff04a6) against everything landed overnight (#313’s data-source half, #315, #321/#324, #323, #325): root cause A (0 sites, confirmed fixed) and root cause C (0 sites, #315’s each.value projection fix confirmed) are both gone. Only root cause B remains (module.ecs_cluster.arn, a Computed attribute crossing a module-output boundary), now cascading to 1 “Unable to compute static value” plus 6 “Unresolvable identity” sites (aws_appautoscaling_target/aws_appautoscaling_policy chain) - down from 236 diagnostics to 8. This is the same already-acknowledged Computed-attribute/module-output architecture question corpus-rds-complete-postgres and corpus-security-group-complete are also blocked on; no action taken here, no new issue filed.

Reproduce it#

go run ./tools/gauntlet run corpus-ecs-fargate

Needs Docker (the emulator is pulled at the pinned digest), the AWS CLI, and a stock terraform or tofu binary on PATH for the cold deploy. The script is live/e2e/corpus-ecs-fargate/run.sh; BREAK=1 corrupts its assertions to show they are load-bearing.