Problem: You need to create multiple similar resources (like 3 EC2 instances). Writing a separate resource block for each one is repetitive.
Solution: for_each loops over a map or set and creates one resource per item — each with its own unique name.
# Instead of writing 3 separate resource blocks...
# Just define one and loop over a map
resource "aws_instance" "main" {
for_each = var.ec2_map # creates one instance per map entry
...
}
Inside the loop you get two values:
each.key → the name of the current item (e.g. "ubuntu")each.value → the data of the current item (e.g. { ami = "...", instance_type = "..." })count |
for_each |
|
|---|---|---|
| Resource names | instance[0], instance[1] |
instance["ubuntu"], instance["amazon-linux"] |
| Access | resource[0] |
resource["ubuntu"] |
| Add new item | Shifts all indexes — can destroy/recreate others | Only adds the new resource |
| Remove item | Shifts all indexes | Only removes that one resource |
for_each is safer and more readable — each resource has a meaningful name, not just a number.
tf-multi-resources/
├── main.tf
├── variables.tf
└── terraform.tfvars
Use a map of objects — each key is the instance name, each value holds its config.
variables.tf
variable "ec2_map" {
type = map(object({
ami = string
instance_type = string
}))
}
terraform.tfvars