1. for_each is best when…
- You need identical numbered resources only
- You iterate over a set/map of named items
- You never use modules
- You replace state
Source: doonops-curriculum/meta-arguments--count-foreach.md
Doonops lesson
count vs for_each vs "for" — stop confusing them with Python loops.
Terraform is NOT Python. To make many similar resources you use count (numbered copies) or for_each (named copies from a map/set).
Meta-arguments count and for_each on modules/resources; for expressions in attributes; dynamic blocks; lifecycle ignore_changes.
count = photocopy 3 identical flyers (page 0,1,2). for_each = print one flyer per city name from a list (Mumbai, Delhi).
Layman words first, then technical detail — read slowly
Beginners search "for loop in Terraform" because they know Python. In Terraform you usually mean one of these:
| You want | Use | Layman |
|---|---|---|
| 3 identical servers | count = 3 | 3 photocopies |
| 1 server per name in a list | for_each = toset(...) | 1 per label |
| Transform a list inside one field | for = expression in attribute | Excel formula inside one cell |
resource "aws_subnet" "private" {
count = 2 ← make 2 subnets
cidr_block = var.cidrs[count.index] ← index 0 then 1
}
Simple: count = "how many clones". count.index = clone number starting 0.
Downside: remove item from middle of list → Terraform may destroy/recreate wrong one (index shift). Exam loves this trap.
variable "subnets" {
default = {
app = "10.0.1.0/24"
db = "10.0.2.0/24"
}
}
resource "aws_subnet" "this" {
for_each = var.subnets ← key = app, db
cidr_block = each.value ← CIDR for that key
tags = { Name = each.key }
}
Simple: each.key = name (app, db). each.value = value (CIDR).
When better: named environments, stable keys, exam answer "use for_each when keys matter".
tags = { for k, v in var.extra_tags : k => v if v != "" }
This builds a map — does NOT create 5 resources by itself.
countfor_eachfor expressionModern HCL — names are examples, not from any third-party course
variable "subnets" {
type = map(string)
default = {
app = "10.0.1.0/24"
db = "10.0.2.0/24"
}
}
resource "aws_subnet" "named" {
for_each = var.subnets
vpc_id = var.vpc_id
cidr_block = each.value
tags = { Name = each.key }
}Terraform runs on your computer — copy this HCL into a folder, then follow the local lab steps below.
Full implementation folder — copy all files, then run terraform commands
Copy every file below into one folder — same as a real repo module. Then run the local lab steps.
Suggested folder: Suggested path: ~/doonops-terraform/08-meta-args/
versions.tfSee file purpose in the code belowterraform {
required_version = ">= 1.9.0"
}
2–3 quick questions before the next module
Quick check — did this module stick?
1. for_each is best when…