count - simple but fragile
count creates N copies of a resource indexed by number.
resource "aws_iam_user" "devs" {
count = length(var.usernames)
name = var.usernames[count.index]
}
The problem: removing alice from ["alice", "bob", "carol"] shifts all indexes - Terraform destroys and recreates bob and carol.
# removing alice causes:
aws_iam_user.devs[0] # destroyed (was alice)
aws_iam_user.devs[1] # destroyed + recreated (was bob, now bob)
aws_iam_user.devs[2] # destroyed + recreated (was carol, now carol)
for_each - stable and explicit
for_each keys resources by a string - removing one item never touches the others.
resource "aws_iam_user" "devs" {
for_each = toset(var.usernames)
name = each.key
}
# removing alice causes only:
aws_iam_user.devs["alice"] # destroyed
# bob and carol are untouched
when to use count
- identical resources with no meaningful name (e.g. 3 identical worker nodes)
- toggling a resource on/off:
count = var.enabled ? 1 : 0
when to use for_each
- any named resource (users, buckets, DNS records, security groups)
- when the set of items will change over time
Originally published at https://bard.sh/posts/count_vs_for_each/
Top comments (0)