7 — count and for_each¶
Folder: none yet — paste this into a scratch root.
Both create multiple instances from one resource block. The difference is how instances are addressed, and that difference decides what happens when the collection changes.
count — positional¶
resource "local_file" "multi" {
count = 3
filename = "/tmp/pet-${count.index}.txt"
content = "This is pet file number ${count.index}"
}
Three separate addressable instances from one block:
The flaw: change count = 3 to count = 1 and re-plan. Terraform proposes destroying
multi[1] and multi[2] — fine. But the real problem shows up when you remove an item
from the middle of a list driving the count. Every subsequent index shifts, and Terraform
reads a shifted index as a different resource: destroy and recreate, not rename.
for_each — keyed¶
variable "pet_names" {
type = set(string)
default = ["fido", "whiskers", "rex"]
}
resource "local_file" "named_pets" {
for_each = var.pet_names
filename = "/tmp/pet-${each.value}.txt"
content = "Meet ${each.value}, a very good pet."
}
Addresses are keyed, not indexed:
The destructive test¶
This single experiment is the entire argument for for_each. Remove "whiskers" from the
set and re-plan:
Only named_pets["whiskers"] is destroyed. "fido" and "rex" are untouched. Contrast
with the count version, where removing a middle element churns everything after it.
Which to use¶
Prefer for_each whenever items can be added to or removed from the middle of a
collection. Reserve count for two cases:
- N genuinely identical copies where position carries no meaning
- the conditional 0/1 pattern — see Conditionals
The type matters¶
count needs an ordered list(string); for_each needs a set(string) or a map. The
core GCP root keeps
both declarations side by side with the
count version commented out directly above the for_each version, specifically so you
can switch between them and diff terraform state list. The GCP versions of these two
sections are Lab 4 and
Lab 5.
for_each also applies to module blocks, not just resources —
Lab 13.
Not the same as dynamic¶
count and for_each repeat whole resources. A dynamic block repeats a nested block
inside one resource. Different mechanism, easily confused — see
Lab 12. There are only two in this
repository, both needing a cloud resource to be worth writing: the lifecycle_rule
generator in the core GCP root and
dynamic "rule" in the sandbox's backend/infra/rbac.tf.
Key takeaway¶
count addresses instances by position, for_each by key, and that one difference decides
whether editing the middle of a collection is a rename or a rebuild. Default to for_each;
reserve count for N identical copies where position means nothing, and for the 0/1
conditional.
Theory: §9 count, for_each & dynamic · Quiz: Variables, expressions & guards · Next: Conditionals