Let's think about it this way for a second
Instead of manually copy-pasting five resource blocks for five servers, adding `count = 5` inside a resource block makes Terraform create it five times over — you can use `count.index` (0,1,2,3,4) in the resource name/tag. `for_each` is for looping over a list/map — it's better than `count` when you want to track items by a 'meaningful key' (like a server name) instead of an index number (0,1,2): if you delete one item from a list, `count` shifts every index and can recreate every resource, while `for_each` leaves the rest of the items untouched. A dynamic block, meanwhile, is for generating nested blocks (like multiple `ingress` rules in a security group) with a loop.
Let's connect this to a real scenario
Writing `for_each = toset(["web", "api", "worker"])` creates three servers (named web, api, worker) — you can reference `each.key`/`each.value` inside the resource. If you delete 'api' from the server list, `for_each` destroys only 'api' and leaves 'web'/'worker' completely untouched — with `count`, the index shift could recreate every server.
Let's look at it together
# count: index-based
resource "aws_instance" "worker" {
count = 3
ami = "ami-0abcdef1234567890"
instance_type = "t3.micro"
tags = {
Name = "worker-${count.index}"
}
}
# for_each: key-based (safer when removing items)
resource "aws_instance" "app" {
for_each = toset(["web", "api", "worker"])
ami = "ami-0abcdef1234567890"
instance_type = "t3.micro"
tags = {
Name = each.value
}
}$ terraform apply
aws_instance.app["api"]: Creating...
aws_instance.app["web"]: Creating...
aws_instance.app["worker"]: Creating...
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.5-minute try-it
Use `for_each` to create three `local_file` resources at once (with different filenames) — delete one item from the list, re-run `apply`, and confirm the remaining files are untouched.
A quick word of caution
You can't use `count` and `for_each` together on the same resource — you have to pick one or the other for each resource type.