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.
| Stage | Verdict | Detail |
|---|---|---|
| Cold deploy | pass | 62 resources, once for real |
| Migrate | pass | 46 of 62 stamped |
| Replan from nothing | pass | genuinely 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 apply | pass | genuine no-op (0 added, 0 changed, 0 destroyed); 46 tofu-estate-tagged objects before, 46 after, no state file either time |
| Drift and reconverge | pass | one object tampered (VPC’s Name tag), plan proposed fixing exactly module.vpc.aws_vpc.this[0], apply changed 1 and the Name tag reconverged |
| Rename | pass | moved 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 block | pass | choudoufu: 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_destroy | not run | |
| Crash between create and destroy (planned) | not run | |
| Teardown (planned) | not run | |
| Plan, review, apply (planned) | not run | |
| Greenfield apply | pass | 62 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-fargateNeeds 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.