Using for_each
in Terraform
The for_each
meta-argument in Terraform allows you to create multiple resource instances based on a map or a set of strings. This is particularly useful when you need to create several similar resources with slight variations.
Basic for_each
Usage
Here's a basic example of using for_each
with a map:
variable "subnets" {
type = map(object({
cidr_block = string
availability_zone = string
}))
default = {
"subnet1" = { cidr_block = "10.0.1.0/24", availability_zone = "us-west-2a" },
"subnet2" = { cidr_block = "10.0.2.0/24", availability_zone = "us-west-2b" }
}
}
resource "aws_subnet" "example" {
for_each = var.subnets
vpc_id = aws_vpc.main.id
cidr_block = each.value.cidr_block
availability_zone = each.value.availability_zone
tags = {
Name = each.key
}
}
In this example, we're creating multiple subnets based on the subnets
variable.
Using for_each
with a Set of Strings
You can also use for_each
with a set of strings:
variable "user_names" {
type = set(string)
default = ["john", "jane", "doe"]
}
resource "aws_iam_user" "example" {
for_each = var.user_names
name = each.value
}
This will create an IAM user for each name in the user_names
set.
Environment-Specific Variables with for_each
You can combine for_each
with environment-specific variables:
variable "environments" {
type = map(object({
instance_type = string
instance_count = number
}))
default = {
dev = { instance_type = "t2.micro", instance_count = 1 }
test = { instance_type = "t2.small", instance_count = 2 }
prod = { instance_type = "t2.medium", instance_count = 3 }
}
}
resource "aws_instance" "example" {
for_each = var.environments[terraform.workspace].instance_count > 0 ? toset(range(var.environments[terraform.workspace].instance_count)) : []
ami = "ami-0c55b159cbfafe1f0"
instance_type = var.environments[terraform.workspace].instance_type
tags = {
Name = "instance-${each.key}"
}
}
This example creates a different number of instances with different instance types based on the current Terraform workspace.
Accessing Resources Created with for_each
When you use for_each
, you access the created resources using the map syntax:
output "subnet_ids" {
value = values(aws_subnet.example)[*].id
}
output "first_instance_id" {
value = aws_instance.example["0"].id
}
Remember, when using for_each
, Terraform creates each resource instance as a separate object in the state, which can be more efficient and easier to manage than using count
for complex scenarios.