patternbashterraformTip
Dynamic blocks eliminate repetitive nested block duplication in Terraform resources
Viewed 0 times
dynamic blocksnested blocksfor_eachiteratorsecurity group rulesingress rulesDRY
Problem
Some Terraform resources require multiple nested configuration blocks (e.g., security group ingress rules, ECS container definitions, policy statements). Writing each block by hand is verbose, repetitive, and difficult to maintain when the list of items comes from a variable.
Solution
Use
dynamic blocks to generate repeated nested blocks from a collection. The content block inside dynamic defines the block body using each.value.variable "ingress_rules" {
type = list(object({
port = number
protocol = string
cidr_blocks = list(string)
}))
default = [
{ port = 80, protocol = "tcp", cidr_blocks = ["0.0.0.0/0"] },
{ port = 443, protocol = "tcp", cidr_blocks = ["0.0.0.0/0"] },
]
}
resource "aws_security_group" "web" {
name = "web-sg"
vpc_id = var.vpc_id
dynamic "ingress" {
for_each = var.ingress_rules
content {
from_port = ingress.value.port
to_port = ingress.value.port
protocol = ingress.value.protocol
cidr_blocks = ingress.value.cidr_blocks
}
}
}Why
Dynamic blocks allow the number and content of nested blocks to be driven by data, making modules flexible and eliminating repetition that would otherwise require copy-paste of nearly identical blocks.
Gotchas
- The iterator label defaults to the dynamic block name (e.g.,
ingress.value) — useiterator = ruleto rename it for clarity - Dynamic blocks can only be used for repeatable nested blocks, not for top-level resource arguments
- Deeply nested dynamic blocks become hard to read — consider flattening complex inputs with
flatten()orlocalpreprocessing
Context
Resources with a variable number of nested configuration blocks driven by user input
Revisions (0)
No revisions yet.