Skip to content

Learn · Modules and iteration

count against for_each, and the index shift

Removing the second of five instances destroys three of them. Not because anything is broken — because count keys are positions.

Positions against names

count gives each instance a number: web[0], web[1], web[2]. for_each gives each one a key from the collection: web["alpha"], web["beta"]. Both produce the same resources, and the difference is what happens when the collection changes.

A number is a position. Take the middle entry out of a list of three and everything after it moves down one — so web[1] now refers to what used to be web[2], and the plan compares the wrong pairs. A key is a name, and taking one out takes out exactly one.

The instances are identical either way. What differs is how the plan decides which one is which, and that decision is made entirely by the key.

The catastrophe, in one edit

Three workers, count = length(var.names), names ["alpha", "beta", "gamma"]. Remove beta. The list is now two long, so web[2] is destroyed — which is correct — and web[1], which held beta, is now compared against gamma and replaced.

Two resources destroyed, one of them for no reason anybody intended, from deleting one line. With five instances and one removed from the middle, it is three.

Before you run it

A count-based resource has five instances. You remove the second entry from the list it counts. How many are destroyed or replaced?

The fix, and what it costs

for_each = toset([...]) keys the instances by their own values, so removing one removes one. That is the fix, and it is almost always the right default.

Switching an existing resource from count to for_each is itself the catastrophe, though: every key changes, so every instance is destroyed and recreated. moved blocks are what make that migration free — one per instance, saying web[0] is now web["alpha"], and the plan comes out empty.

Try this
- for_each = toset(["a", "b", "c"])
+ for_each = toset(["a", "c"])

Watch: Exactly one subnet destroyed — and what that does to the workers sitting in the others.

aws_subnet.cidr_blockWhy the blast radius is what it is: a subnet cannot be re-addressed, so every instance the shift touches is rebuilt rather than updated.

The plan

The same service every claim above was made about. Nothing here is graded — load whatever you like, or change nothing and read what the configuration already produces.

No change loaded — the configuration as it stands.
Plan: 0 to add, 0 to change, 0 to destroy.

Nothing in this plan is destroyed.

Answer the question above first.Read a plan
Everything you do here stays in this browser.Part of liter8.sh · v0.1.0