When I first wanted to do nested looping in terraform, a lot of information online said it wasn’t possible. I learned eventually that it is possible, with one caveat, and this is the post I wish I’d found back then.
Imagine we’ve got a map of items:
locals {
items = {
"value1": {...},
"value2": {...},
...
"valueN": {...},
}
}
The way you loop over these items in a flat fashion is like this with a for_each expression
for_each = local.items
## each.key is `valueX`
## each.value is the object at that key
I’ll use the example of DataDog dashboard widgets throughout, to keep the demos consistent. With this loop, we could define some graph templates and generate them with a for_each.
resource "datadog_dashboard" "new_dash" {
for_each = local.items
widget {
...
query = each.value.query
...
}
}
The standard for_each approach does not support nesting though.
Imagine this use case: for a list of services, I want to generate a set of graphs monitoring specific kinds of error produced by that service, grouped by their service.
If I were writing that in Go it would look like:
for _, service := range service {
serviceGroup := datadog.NewGroup()
for _, graph := range service.graphs {
serviceGroup.Add(graph)
}
}
But the same syntax doesn’t work in Terraform. A second for_each statement won’t work that way.
NB: IF YOU’RE JUST SCANNING THIS POST, THE FOLLOWING APPROACH DOES NOT WORK. KEEP READING.
locals {
services = {
service1": {
"serviceName": "...",
"errorNames": [....]
},
"service2": {
"serviceName": "...",
"errorNames": [....]
},
}
}
resource "datadog_dashboard" "new_dash" {
for_each = local.services
widget {
# a group of graphs under a heading
group_definition {
title = "each.value.serviceName"
#
# it will break here
#
for_each = each.value.errorNames
widget {...}
}
}
}
You’d imagine we could just nest for_each statements like this, but we can’t.
One option is to use the flatten(...) method, to essentially un-nest the values and create a flat list with one element per thing you want to create.
This would work fine if you don’t care about grouping the results, but in our case and in many use cases, the nesting represents a relationship between the sub-elements which you want to retain.
The solution is to use dynamic blocks. These let you generate one block per iterated value, and crucially allows you to nest these iterators.
Here’s how it works with the same example:
locals {
services = {
service1": {
"serviceName": "...",
"errorNames": [....]
},
"service2": {
"serviceName": "...",
"errorNames": [....]
},
}
}
resource "datadog_dashboard" "new_dash" {
# add dynamic in front of the block to repeat
# this gives us one widget per service
dynamic "widget" {
# loop over services
for_each = local.services
# and name the iterator variable
iterator = service
# content keyword separates the iteration syntax and content
content {
group_definition {
title = "each.value.serviceName"
# another dynamic
# one widget per error_name
dynamic "widget" {
# refer to the iterator variable "service"
# and loop over its errors
for_each = service.value.errorNames
iterator = "error_name"
content {...}
}
}
}
}
}
That’s how we do nested looping in Terraform. A few things to note:
content block for dynamic widgets.iterator value allows you to name the variable which holds the item. Do NOT put quotes around your iterator variable name, e.g. iterator = "service", which I found will serve cryptic errors.Because this is a dynamic block feature, we can only iterate on blocks. You can’t place loops wherever you wish. They have to go inside the dynamic block.
You can’t loop over services, then over errorNames without them each corresponding to a block. If you want to do that though, flattening is probably fine for your use case.
HRV & Me: Taming a messy stressy mind - [Mar 8, 2026]
Resonance - [Feb 8, 2026]
Where Angels Fear to Tread -- EM Forster - [Jul 13, 2025]
Steve Jobs -- Walter Isaacson - [Jul 10, 2025]
The Fifth Risk -- Michael Lewis - [Jul 10, 2025]
The Ride of a Lifetime -- Bob Iger - [Jul 10, 2025]
James -- Percival Everett - [Jul 3, 2025]
Great Expectations -- Charles Dickens - [Jul 1, 2025]
Hillbilly Elegy -- JD Vance - [Jun 23, 2025]
Principles - [Jun 10, 2025]
Revenge of the Tipping Point -- Malcolm Gladwell - [Jun 9, 2025]
The Grand Babylon Hotel -- Arnold Bennett - [Jun 6, 2025]
The Seven Husbands of Evelyn Hugo -- Taylor Jenkins Reid - [Jun 4, 2025]
Rebecca -- Daphne du Maurier - [Jun 3, 2025]
A Promised Land - Barack Obama - [May 29, 2025]
Less - Andrew Sean Greer - [May 29, 2025]
Careless People - Sarah Wynn-Williams - [May 13, 2025]
Looking Glass War - John Le Carre - [May 7, 2025]
A Murder of Quality - John Le Carre - [May 4, 2025]
London Marathon 2025: Training Retrospective - [May 1, 2025]
The Human Factor - Graham Greene - [Apr 29, 2025]
London Marathon 2025: Race Review - [Apr 28, 2025]
Photos: London Marathon 2025 - [Apr 27, 2025]
Spectating the London Marathon 2025 [Sunday 27th April] - [Apr 27, 2025]
London Marathon 2025: Week 16 - [Apr 26, 2025]
Call for the Dead - John Le Carre - [Apr 23, 2025]
London Marathon 2025: Week 15 - [Apr 21, 2025]
The Manchurian Candidate - Richard Condon - [Apr 16, 2025]
London Marathon 2025: Week 14 - [Apr 13, 2025]
London Marathon 2025: Week 13 - [Apr 5, 2025]
London Marathon 2025: Week 12 - [Mar 30, 2025]
Effortless - Greg Mckeown - [Mar 26, 2025]
Leading - [Mar 26, 2025]
London Marathon 2025: Week 11 - [Mar 23, 2025]
London Marathon 2025: Week 10 - [Mar 16, 2025]
London Marathon 2025: Week 9 - [Mar 9, 2025]
London Marathon 2025: Week 8 - [Mar 2, 2025]
London Marathon 2025: Week 7 - [Feb 22, 2025]
London Marathon 2025: Week 6 - [Feb 16, 2025]
Problems & [Meta] Problem Solving - [Feb 16, 2025]
Little Dribbling - Bill Bryson - [Feb 14, 2025]
Bring Up the Bodies - Hilary Mantel - [Feb 10, 2025]
London Marathon 2025: Week 5 - [Feb 9, 2025]
Three Zero - [Feb 9, 2025]
The iPad mini has genuinely changed my life [no hyperbole] - [Feb 3, 2025]
London Marathon 2025: Week 4 - [Feb 2, 2025]
Coming AI: Valuing Humans in a world where they have no economic value - [Jan 28, 2025]
Value & Price - [Jan 28, 2025]
The Vegetarian - Han Kang - [Jan 27, 2025]
Wolf Hall - Hilary Mantel - [Jan 27, 2025]
London Marathon 2025: Week 3 - [Jan 26, 2025]
Deriving my own proof for Unitary matrices - [Jan 19, 2025]
London Marathon 2025: Week 2 - [Jan 19, 2025]
David Copperfield - Charles Dickens - [Jan 17, 2025]
London Marathon 2025: Week 1 - [Jan 12, 2025]
NYC & DC '24 - [Jan 9, 2025]
Linear Algebra Playground - [Jan 8, 2025]
Configuring an IKEA wireless light switch: Saving you the pain - [Jan 7, 2025]
Goals & Goal-setting - [Jan 7, 2025]
Organisation - [Jan 7, 2025]
Digital Feeds - [Jan 6, 2025]
London Marathon 2025: Training Begins - [Jan 5, 2025]
Everything I've read in 2025 (so far) - [Jan 1, 2025]