Terraform - Loop over a dictionary using for_each

by
Jeremy Canfield |
Updated: September 19 2023
| Terraform articles
for_each can be used to:
- loop through the items is a list
- loop through the keys and values in a dictionary (this article)
Here is a simple example that illustrates how you can use for_each to loop through keys and values.
resource "aws_vpc" "my-vpc" {
for_each = {
"us-east-2a" = "10.11.1.0/22"
"us-east-2b" = "10.11.2.0/22"
"us-east-2c" = "10.11.3.0/22"
}
availability_zone = each.key
cidr_block = each.value
tags = {
Name = "my-vpc-${each.key}"
}
}
Often, you will be looping through a list that in one of your terraform.tfstate files that was generated from a data block or resource block.
For example, if you create an Amazon Web Services (AWS) SSL certificate using the aws_acm_certificate resource, your terraform.tfstate file should contain something like this. Notice in this example that the domain_validation_options list contains keys and values (a dictionary).
"resources": [
{
"instances": [
{
"attributes": {
"domain_validation_options": [
{
"domain_name": "*.example.com",
"resource_record_name": "_4be4327c41234567890cf0b869d11234.example.com.",
"resource_record_type": "CNAME",
"resource_record_value": "_97db6123456789123456789dd8dc42a0.abcdefg.acm-validations.aws."
},
{
"domain_name": "example.com",
"resource_record_name": "_4be4327c41234567890cf0b869d11234.example.com.",
"resource_record_type": "CNAME",
"resource_record_value": "_97db6123456789123456789dd8dc42a0.abcdefg.acm-validations.aws."
}
],
Here is how you could loop over keys and values (dictionary) in the domain_validation_options list using for_each and for.
resource "aws_route53_record" "example_com_cname_records" {
for_each = {
for item in data.terraform_remote_state.acm_certificates.outputs.example_com_certificate.domain_validation_options : item.domain_name => {
name = item.resource_record_name
record = item.resource_record_value
type = item.resource_record_type
}
}
allow_overwrite = true
name = each.value.name
records = [each.value.record]
ttl = 300
type = each.value.type
zone_id = data.aws_route53_zone.example_com_zone.zone_id
}
Did you find this article helpful?
If so, consider buying me a coffee over at