for_each
for_each creates one resource per item in a map or set, keyed by name instead of index.
for_each = toset(["a", "b"])for_each creates one resource per entry in a map or set. Unlike count, each instance is identified by a stable key rather than a numeric position, so adding or removing one item does not disturb the others.
each.key and each.value
Inside the block, each.key and each.value refer to the current item.
Addressing
Instances are addressed by key: aws_s3_bucket.env["dev"].
Example
resource "aws_s3_bucket" "env" {
for_each = toset(["dev", "staging", "prod"])
bucket = "soundscode-${each.key}-data"
tags = {
Environment = each.key
}
}
# Reference one: aws_s3_bucket.env["prod"].idWhen to use it
- A team manages S3 buckets for multiple environments by passing a map to for_each, giving each bucket a stable key even if one is deleted mid-list.
- An engineer creates one IAM user per team member by passing a set of usernames to for_each, so removing a user deletes only that user without reshuffling indexes.
- A module creates one subnet per availability zone by iterating over a map of AZ-to-CIDR with for_each, producing subnets keyed by AZ name.
More examples
for_each with a set of strings
Creates one S3 bucket per item in the set, keyed by the bucket's purpose name rather than a fragile numeric index.
variable "buckets" {
type = set(string)
default = ["logs", "backups", "assets"]
}
resource "aws_s3_bucket" "env" {
for_each = var.buckets
bucket = "myapp-${each.key}"
}for_each with a map
Iterates over a map of AZ-to-CIDR to create one subnet per entry, referencing each.key and each.value for the AZ and CIDR.
variable "subnets" {
type = map(string)
default = {
"us-east-1a" = "10.0.1.0/24"
"us-east-1b" = "10.0.2.0/24"
"us-east-1c" = "10.0.3.0/24"
}
}
resource "aws_subnet" "az" {
for_each = var.subnets
vpc_id = aws_vpc.main.id
availability_zone = each.key
cidr_block = each.value
}Reference for_each resource
Shows how to reference a specific for_each resource by key and how to build a map of all resulting ARNs using a for expression.
# Access one specific instance by key
output "logs_bucket_arn" {
value = aws_s3_bucket.env["logs"].arn
}
# Access all arns as a map
output "all_bucket_arns" {
value = { for k, v in aws_s3_bucket.env : k => v.arn }
}
Discussion