Security group rules, listeners and IAM statements often come from data, not fixed code.
Some arguments are nested blocks (ingress { ... } inside a security group, setting { ... } in an Elastic Beanstalk environment). count/for_each work only on whole resources, so to generate blocks from a collection you use a dynamic block:
dynamic "ingress" { for_each = var.rules content { from_port = ingress.value.port ... } }
The iterator is named after the block (ingress.key, ingress.value), or set iterator = rule. Use them when the data truly varies; for two fixed blocks, writing them out is clearer.
The other frequent need is flattening nested structures for for_each. For example, a map of networks each with several subnets: produce one flat list with flatten, then key it uniquely:
{ for s in local.subnet_list : "${s.network}.${s.name}" => s }
Choose keys that are stable and meaningful, because they become part of resource addresses.
setproduct builds combinations (every environment times every region). try() and optional() attributes with defaults make variable objects pleasant to fill in.
Readability is the real constraint: if a reader needs terraform console to understand a local, consider simplifying the input shape instead.
Example
variable "networks" {
default = {
app = { subnets = ["a", "b"] }
data = { subnets = ["a"] }
}
}
locals {
subnet_list = flatten([
for net, cfg in var.networks : [
for s in cfg.subnets : { network = net, name = s }
]
])
subnets = { for s in local.subnet_list : "${s.network}.${s.name}" => s }
}
resource "terraform_data" "subnet" {
for_each = local.subnets # keys: app.a, app.b, data.a
input = "${each.value.network}-${each.value.name}"
}
output "keys" { value = keys(local.subnets) } # ["app.a", "app.b", "data.a"]Remember
- dynamic "block" { for_each, content } generates nested blocks
- flatten nested data, then build a map with stable unique keys
- Prefer explicit blocks when the set is small and fixed
Watch out for
- Using list positions as keys after flattening, which brings back count's index-shift problem.