liveBook · Manning

For_each meta-argument

As explained in Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu

The for_each meta-argument creates one Terraform resource or module instance for each item in a collection or set.

Suppose several EC2 instances need the same basic configuration but different names and instance types. Put their configurations in a map and assign it to `for_each` in one resource block. Terraform creates an instance for each entry; `each.key` supplies its name, while `each.value` supplies its settings. The same approach works with modules. section 4.8.2

Instances with different sizes

A `machine_configs` map can pair `web_server` with `t3.nano` and `background_processor` with `t3.micro`. In an `aws_instance` block, set `for_each = local.machine_configs`, `instance_type = each.value.type`, and the `Name` tag to `each.key`. section 4.8.2

`for_each` accepts a map, object, or set, rather than the integer used by `count`. For a set, the element is both `each.key` and `each.value`; this suits resources that differ by one value, such as VPC endpoints for selected services. A list cannot be passed directly. `toset` converts it, but removes duplicates and ordering. A block can use either `for_each` or `count`, not both. section 4.8.2 section 4.8

The collection must be known when Terraform plans, so it can create the necessary resource-graph nodes. Values derived from resource attributes or functions such as `timestamp` and `uuid` can cause a planning error. Prefer an input value over a computed resource attribute when possible. Another workaround is to use a known `count` and select configuration with `count.index`; splitting deployment into batches is possible but complicates normal deployment and teardown. section 4.8.4 section 5.7.5

Do not confuse resource or module `for_each` with the similarly named parameter in a `dynamic` block. The latter repeats nested configuration blocks, such as security-group ingress rules, rather than creating resource instances. section 4.10

Listing 4.36 Using for_each to create resources with different parameters
locals {
  machine_configs = {
    "web_server" = {
      type = "t3.nano"
    }
    "background_processor" = {
      type = "t3.micro"
    }
  }
}
 
resource "aws_instance" "for_each" {
  for_each      = local.machine_configs                                         #1
  subnet_id     = var.subnet_id                                                 #2
  instance_type = each.value.type                                               #3
  ami           = data.aws_ami.main.id                                          #4
  tags = {
    Name = each.key                                                             #5
  }
}
 
locals {                                                                        #6
  vpc_endpoints = [                                                             #7
    "s3",
    "dynamodb"
  ]
}
 
data "aws_region" "current" {}                                                  #8
 
resource "aws_vpc_endpoint" "main" {                                            #9
  for_each     = toset(local.machine_configs)                                   #10
  vpc_id       = var.vpc_id
  service_name = "com.amazonaws.${data.aws_region.current.name}.${each.value}"  #11
}

The listing shows `each.key` and `each.value` assigning different names and instance types from one resource block. section 4.8.2

How Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu covers it

How deep it goes
Works through map and set usage, then explains plan-time failures and practical workarounds.
Examples
Uses differently sized EC2 instances, VPC endpoints, and security-group ingress rules.
What it assumes
Assumes familiarity with resource and module blocks while defining how for_each exposes collection keys and values.
What you can do after
Build it from scratch using collection-driven instances and diagnose planning errors caused by unavailable values.
How it connects
Connects for_each to count, Terraform resource graphs, computed values, and dynamic blocks.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu. The section links point to the parts of the book it draws on.