terraform-aws-modules/terraform-aws-eks examples/basic (tag v9.0.0)

Source: https://github.com/terraform-aws-modules/terraform-aws-eks.git at v9.0.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

Clear. Every headline stage passes.

StageVerdictDurationDetail
Cold deploypass1m22s54 resources, genuinely cold, genuinely unmarked
Migratepass1m29s25 of 54 resource instances stamped, 25 of 25 confirmed via the AWS CLI; 5 record-backed instances seeded into the implied local record store (#364)
Replan from nothingpass18slive-plan runs to completion with ZERO Error diagnostics and reports “No changes. Your infrastructure matches the configuration.” - the record-backed worker launch configuration’s enable_monitoring/root_block_device/user_data all now agree with the config’s own desired value (lex00/floci#132 for the first two, configuredAttrsSeed’s residue-record pre-read seed in internal/live/projection/build.go for the third)
No-op applypass20sgenuine no-op (0 added, 0 changed, 0 destroyed); 25 tofu-estate-tagged objects before, 25 after
Drift and reconvergepass41sone object tampered (VPC’s Name tag), plan proposed fixing exactly module.vpc.aws_vpc.this[0], apply changed 1 and the Name tag reconverged
Renamepass1m18smoved block: aws_security_group.worker_group_mgmt_two renamed with zero churn (0 add, 1 change, 0 destroy), marker rewritten in place; live-mv: aws_security_group.all_worker_mgmt 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 blockpass1m1schoudoufu: deleting aws_security_group.worker_group_mgmt_one’s block (plus emptying the one argument that referenced it) proposed 2 resource action(s), address-for-address and action-for-action identical to stock’s oracle on cold_deploy’s own state; applied cleanly; the security group is genuinely gone from the live account, read via the AWS CLI, not choudoufu’s own report; classifyOrphans did not withhold any destroy because no other aws_security_group.worker_group_mgmt_one block is declared anywhere in this config; the next plan is empty
Change countpass3m47schoudoufu: scaling aws_security_group.count_test from 2 to 1 destroyed exactly count_test[1], the higher index (0 add, 0 change, 1 destroy), and count_test[0] kept BOTH its live id (sg-ee7685f0f96467ea0) and its tofu-address marker (aws_security_group.count_test:0, colon-escaped per live/MARKERS.md) across it, read back through the AWS CLI rather than choudoufu’s own report; the destroyed group (sg-d3efd6a044d3fed9e) is genuinely gone from the account; scaling back from 1 to 2 created exactly count_test[1] (1 add, 0 change, 0 destroy) as a NEW object under a NEW GroupId (sg-51f3c99839a129720, was sg-d3efd6a044d3fed9e) carrying aws_security_group.count_test:1, while count_test[0] stayed untouched throughout; the next plan is empty. Stock oracle (G0): plain terraform, its own working directory, state and VPC, standing the IDENTICAL 2-instance count block up for real against the same idle floci account, shows the identical shape - destroy the higher index only (count_test[1]=sg-363450d59bf8c6283), create it back under a new id (sg-5199f5ef361f900fe), count_test[0]=sg-10da9263978406330 unchanged both times - and is torn down again before choudoufu’s own side runs. Synthetic block, and why: terraform-aws-eks v9.0.0 has no scalable count knob to drive - every count in the module is a boolean create toggle (var.create_eks ? 1 : 0 and siblings), and the one length-driven knob (local.worker_group_count) drives only aws_autoscaling_group, aws_launch_configuration and aws_iam_role_policy_attachment, all untaggable (no tags argument in the provider schema, so no marker surface for this stage’s identity assertion), and dropping a worker group also rewrites kubernetes_config_map.aws_auth, which aggregates every worker role, so the plan would carry changes alongside the destroy. aws_security_group.count_test is the sanctioned fallback per live/GAUNTLET.md #8, of a type this estate already exercises three times, at an address nothing else in the config names. BREAK_COUNT=1 confirms the check is load-bearing: asserting the WRONG instance (count_test[0], the survivor) was destroyed makes this stage report fail.
Replace with create_before_destroypass1m1schoudoufu: changing aws_security_group.worker_group_mgmt_two_renamed’s ForceNew name_prefix argument proposed a forced replace at the same declared address (Plan: 3 to add, 1 to change, 3 to destroy.), applied cleanly; the old security group is confirmed gone via the AWS CLI (InvalidGroup.NotFound) and the new group (sg-9bc010951e39f9ee7) carries the marker; the local record store’s record at the same address now names the new object’s id, not the destroyed one (sg-b5b0ad2f6f5e53c47 -> sg-9bc010951e39f9ee7); the next plan proposes no resource action; stock oracle on cold_deploy’s own state (F-ORACLE) also proposes replacing the security group at the same address (Plan: 3 to add, 1 to change, 3 to destroy., plan only, not applied - it shares floci’s account with $ADOPTED); BREAK=replace confirms a manufactured marker collision is reported loudly (“Two live resources claiming one slot”) rather than silently proposed as nothing. Scope note: this exercises OpenTofu’s default destroy-then-create ordering, not the create_before_destroy variant the stage’s Title names; also scope note: the section originally targeted all_worker_mgmt_renamed (Part D’s own live-mv leg) and found a genuine, separate defect (mv.go’s propagateModuleRename skipped MoveRecord for a same-module live-mv rename, leaving the local record stale even though the marker moved correctly) - FIXED on the gauntlet/mv-rekey branch, GitHub issue #412 (propagateModuleRename now calls MoveRecord unconditionally for the renamed resource’s own key before the moduleRenameBoundary guard); see this section’s own header comment for the fix and corpus-autoscaling-complete’s/corpus-ecs-fargate’s matching ones in this same unit. This script was not re-run for #412, so this detail string still describes the pre-#412 run until this estate’s next real run.
Crash between create and destroynot run
Teardownnot run
Plan, review, applypass1m43sone argument edited (aws_security_group.worker_group_mgmt_one gains tags = { Reviewed = “yes” }), “plan -out=approved.tfplan” wrote a 81929-byte stock-format plan file whose whole change set is one update on aws_security_group.worker_group_mgmt_one; the world then moved out of band (the VPC vpc-18605b8d’s Name tag, through the AWS CLI, never through choudoufu) and “apply approved.tfplan” refused with “The approved plan no longer matches the live system” at exit 3, classifying the drift under “This apply would do, and the approved plan does not include:” and naming both module.vpc.aws_vpc.this[0] and the live vpc-18605b8d it was computed against, with “Exit status 3” spelled out for a pipeline; nothing was applied - sg-6434714093ab4739b still carried no Reviewed tag, read back through the AWS CLI rather than from the absence of an “Apply complete!” line. Inverted control on the same run (the shape live/smoke/scenarios/apply-what-was-approved.sh reasons out): with the tag put back and nothing else changed, the IDENTICAL file applied - 0 added, 1 changed, 0 destroyed - and sg-6434714093ab4739b read back with Reviewed=yes, so the refusal is earned by the drift and not handed out to every plan file. The reviewed change was in-place from end to end: sg-6434714093ab4739b kept its live id across the whole part, so PART D/E/F/G below still start from the objects STAGE 2 stamped. BREAK_APPROVAL=1 asserts stage 12’s own recorded Break line (apply the planfile after a mutation and expect success) and correctly fails
Greenfield applypass2m25s54 resources from nothing, cluster marker verified via the AWS CLI, 54 records under the implied local record store (#364 A2), replan empty, stock oracle in its own namespace matches structurally on cluster status/version, ASG count/desired-capacities, and cluster-owned security-group count
Strict profile (not a headline stage)not run

Last run at commit 933618dec4 on 2026-09-08T22:17:50Z, exit code 0, against emulator image ghcr.io/lex00/floci@sha256:a39185cc3971d0188663d61043cb038dff1260d8a975b1aa72c4e2bb1feac3cb. Stale: the current pin is ghcr.io/lex00/floci@sha256:d9207de14c919f4bfa50e956376cc441970f3679aabfdd43f3dbf4b779b20805. Total run time 15m27.2s. Oracle: stock terraform 1.16.1, stock tofu 1.12.6 (matches the current pin).

Landed 9717459fd3 (2026-08-18). Crossed by an agent whose worktree, like the original rds-complete-postgres crossing, predates the lambda-simple crossing’s live-import child-module fix (cec3c4b9b1) - migrate is recorded fail here (‘3 of 4 root-module resources stamped, 50 non-root instances not considered’) because that’s what the agent’s own stale base observed. Given rds-complete-postgres’s own re-verification confirmed cec3c4b9b1 generalizes cleanly to a different estate’s module-nested resources, this row very likely also improves once re-verified against current main - flagged for the same re-verification treatment, not yet done. test_plan independently fails on unadmitted default_/VPN-gateway types (overlapping #305’s pattern), undeclared-record-store logical resources, and 7 correctly-conservative count-index refusals (element() over a list, which the checker cannot statically prove injective - not a defect). Two real, generalizing floci gaps found and fixed but NOT YET merged/published: EKS worker AMI discovery (AWS-owned AMI catalog lookup, owner 602401143452/801119661308, evaluated unconditionally by every terraform-aws-eks version) and AutoScalingGroup SuspendProcesses/ResumeProcesses (unimplemented, but the AWS provider calls SuspendProcesses unconditionally around ASG creation on default settings - blocks any aws_autoscaling_group apply, not just EKS’s). Filed as lex00/floci#55, PR lex00/floci#56, pushed but not merged - the currently-pinned floci image predates both fixes. Follow-up pass 2026-08-19: confirmed lex00/floci#55/PR#56 (EKS worker AMI catalog, ASG SuspendProcesses/ResumeProcesses) merged and published, current pin well past that point - cold_deploy passes cleanly with no FLOCI_IMAGE override, no new floci gap found. migrate was recorded fail on stale script assertions only (checking for issue #59’s old root-module-only live-import scope) - the real, current result is a clean PASS: cec3c4b9b1’s child-module live-import fix (already confirmed reaching corpus-rds-complete-postgres) generalizes here too, 25 of 54 instances eligible and stamped (0 failed), 29 skipped legitimately (27 untaggable-by-design, 2 unadmitted-type). test_plan’s real wall shrank sharply once migrate covers the whole module tree: #305’s default_ trio and the VPN-gateway unadmitted sites are gone entirely (admitted and stamping cleanly now); real remaining causes are kubernetes_config_map.aws_auth (1 site, a non-AWS-tag provider resource with no marker/discovery path in this codebase at all - filed as #326, DEFER/design-call caliber matching #309, not attempted), 4 correctly-RULE’d logical-resource refusals (3 correct no-record_store refusals plus #314’s already-tracked local_file gap), and 4 genuinely-unresolvable count-index sites (element(subnet[*].id, count.index), PARITY/RULE, correctly conservative). run.sh’s own header/assertions rewritten and re-verified (clean run plus a BREAK=1 mutation check) to match this real picture. Follow-up pass 2026-08-20 (issue #326 fix, re-crossed for real): the prior handoff note claiming #326’s commit (9131275487) had “fully landed on local main” was WRONG - it sat on an unmerged branch (live/kubernetes-table-rows) whose base predated #331, #337, #343/#344, #348, #349 and the dynamodb/autoscaling crossing work. Merged it into a fresh worktree off current local main (f294af5838), resolved the generated-artifact conflicts by combining both sides’ deltas and re-running the real generators rather than hand-computing totals (852f52073f the merge, a990112e26 the regenerated derived artifacts), full fast tier green. Re-crossed this estate for real against a live floci container with that merge: kubernetes_config_map.aws_auth’s “unadmitted-type” refusal is CONFIRMED GONE - zero occurrences of “Rule: unadmitted-type.” and zero mentions of “kubernetes” anywhere in live-plan’s output, asserted as a negative control in run.sh with BREAK=1 flipping the expectation. The 4 logical-resource and 4 count-index sites are unchanged (8 Error diagnostics total, asserted by count) - test_plan stays fail, this estate does NOT reach 5/5. Migrate’s own accounting is also unchanged in total (25/54 eligible, 29 skipped) but changed in KIND for this one site: kubernetes_config_map.aws_auth moves from an outright “unadmitted” refusal to a genuinely-attempted verification that reports MISSING with a precise, different, real reason - “Provider … kubernetes could not be used … Dynamic value in static context: Unable to use data.aws_eks_cluster_auth.cluster / data.aws_eks_cluster.cluster in static context, which is required by provider.kubernetes.” The kubernetes provider block is itself configured from another provider’s live output (the EKS cluster’s endpoint/token), which live-import’s no-state, no-apply verification pass cannot evaluate. This is a distinct, real, narrower wall than #326’s - #326 admitted the TYPE (identity resolves, plan-time refusal gone); this is a separate provider-config-from-live-data limitation, same family as #313’s own out-of-scope boundary, DEFER-caliber (stock OpenTofu is never asked this question - a real plan/apply always has other resources’ already-applied state to read for the same data sources). Not attempted here, not filed as a fresh issue since it blocks nothing #326 was scoped to fix and this estate’s test_plan stage was already failing for the RULE/PARITY reasons above regardless. Commented on #326 with this measured outcome.

Reproduce it#

go run ./tools/gauntlet run corpus-eks-basic

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-eks-basic/run.sh; BREAK=1 corrupts its assertions to show they are load-bearing.