0
0
Terraformcloud~15 mins

Dynamic blocks vs for_each decision in Terraform - Trade-offs & Expert Analysis

Choose your learning style9 modes available
Overview - Dynamic blocks vs for_each decision
What is it?
In Terraform, dynamic blocks and for_each are two ways to create multiple similar resources or nested blocks efficiently. Dynamic blocks let you generate nested blocks inside a resource or module based on a list or map. The for_each argument lets you create multiple instances of a resource or module based on a collection. Both help avoid repeating code when you want many similar items.
Why it matters
Without dynamic blocks or for_each, you would have to write repetitive code for each similar resource or nested block, which is error-prone and hard to maintain. These features save time, reduce mistakes, and make your infrastructure code cleaner and easier to update. They help you manage complex infrastructure setups with many similar parts.
Where it fits
Before learning this, you should understand basic Terraform resources, variables, and how to write simple blocks. After this, you can learn about modules, advanced expressions, and how to organize large Terraform projects efficiently.
Mental Model
Core Idea
Dynamic blocks generate repeated nested blocks inside a resource, while for_each creates multiple separate resource instances from a collection.
Think of it like...
Imagine you are organizing a party. For_each is like inviting multiple guests by sending each their own invitation card (separate resources). Dynamic blocks are like writing multiple menu items inside one invitation card (nested blocks inside one resource).
Terraform Resource
┌─────────────────────────────┐
│ Resource (e.g., aws_security_group) │
│ ┌───────────────────────┐ │
│ │ Nested Blocks (e.g.,  │ │
│ │ ingress, egress)      │ │
│ │ ┌───────────────┐     │ │
│ │ │ Dynamic Block │     │ │
│ │ │ (repeats inside│     │ │
│ │ │ one resource) │     │ │
│ │ └───────────────┘     │ │
│ └───────────────────────┘ │
└─────────────────────────────┘

Multiple Resources
┌───────────────┐  ┌───────────────┐
│ Resource #1   │  │ Resource #2   │
│ (for_each)   │  │ (for_each)   │
└───────────────┘  └───────────────┘
Build-Up - 6 Steps
1
FoundationUnderstanding Terraform Resources
🤔
Concept: Learn what a Terraform resource is and how it defines infrastructure components.
A Terraform resource is a block that describes one piece of infrastructure, like a server or a firewall rule. You write a resource block with a type and a name, then specify its settings. For example, an AWS EC2 instance resource defines a virtual machine with its properties.
Result
You can create and manage one infrastructure component with a resource block.
Knowing what a resource is helps you understand what you will repeat or generate dynamically later.
2
FoundationBasic for_each Usage in Terraform
🤔
Concept: Use for_each to create multiple resource instances from a list or map.
You can add for_each to a resource block to tell Terraform to make one resource for each item in a collection. For example, if you have a list of server names, for_each creates one server resource per name automatically.
Result
Terraform creates multiple resources, one per item in the collection, without repeating code.
for_each lets you scale your infrastructure code by turning one block into many resources.
3
IntermediateIntroduction to Dynamic Blocks
🤔
Concept: Dynamic blocks generate repeated nested blocks inside a single resource based on a collection.
Some resources have nested blocks, like firewall rules inside a security group. Dynamic blocks let you write one block that repeats inside the resource for each item in a list or map. This avoids writing many nested blocks manually.
Result
Terraform creates multiple nested blocks inside one resource, each configured from the collection items.
Dynamic blocks help when you want to repeat parts inside a resource, not create multiple resources.
4
IntermediateComparing for_each and Dynamic Blocks
🤔Before reading on: do you think for_each and dynamic blocks can always replace each other? Commit to your answer.
Concept: Understand when to use for_each versus dynamic blocks based on what you want to repeat.
for_each creates multiple separate resources or modules, each independent. Dynamic blocks repeat nested blocks inside one resource. Use for_each when you want many resources. Use dynamic blocks when you want one resource with many nested parts.
Result
You can decide the right tool to avoid code duplication and match your infrastructure design.
Knowing the difference prevents mistakes like trying to use dynamic blocks to create multiple resources or vice versa.
5
AdvancedUsing Dynamic Blocks with Complex Expressions
🤔Before reading on: do you think dynamic blocks can handle conditional logic inside repeated blocks? Commit to your answer.
Concept: Dynamic blocks can include conditions and complex expressions to control which nested blocks are created.
Inside a dynamic block, you can use if statements and expressions to include or skip certain nested blocks based on variables or other inputs. This makes your resource flexible and adaptable to different scenarios.
Result
Terraform creates only the nested blocks that meet your conditions, making your code more efficient.
Understanding conditional logic inside dynamic blocks allows you to write smarter, more maintainable infrastructure code.
6
ExpertPerformance and State Implications of for_each vs Dynamic Blocks
🤔Before reading on: do you think using for_each or dynamic blocks affects Terraform state size and plan speed? Commit to your answer.
Concept: Using for_each creates multiple resource instances, each tracked separately in state, while dynamic blocks keep one resource with multiple nested blocks, affecting state and plan behavior differently.
for_each results in many resource objects in state, which can slow down Terraform operations if overused. Dynamic blocks keep state smaller by nesting inside one resource. However, dynamic blocks can be less flexible if you need to manage nested blocks independently.
Result
Choosing between for_each and dynamic blocks impacts Terraform performance and how you manage changes.
Knowing state and performance tradeoffs helps you design scalable and maintainable Terraform configurations.
Under the Hood
Terraform parses the configuration and builds a graph of resources. for_each duplicates the entire resource block for each item, creating separate resource instances with their own lifecycle. Dynamic blocks generate multiple nested blocks inside a single resource during the plan phase by iterating over a collection and injecting repeated blocks. Terraform then manages these nested blocks as part of the parent resource's state.
Why designed this way?
Terraform was designed to model infrastructure as resources with clear lifecycles. for_each fits this by creating multiple independent resources. Dynamic blocks were added later to handle cases where providers expect repeated nested blocks inside one resource, avoiding the need for many separate resources. This design balances flexibility and provider compatibility.
Terraform Configuration
┌───────────────────────────────┐
│ for_each                      │
│ ┌───────────────┐             │
│ │ Resource #1   │             │
│ ├───────────────┤             │
│ │ Resource #2   │             │
│ └───────────────┘             │
│                               │
│ Dynamic Blocks                │
│ ┌─────────────────────────┐ │
│ │ Single Resource         │ │
│ │ ┌─────────────────────┐ │ │
│ │ │ Nested Block #1     │ │ │
│ │ │ Nested Block #2     │ │ │
│ │ └─────────────────────┘ │ │
│ └─────────────────────────┘ │
└───────────────────────────────┘
Myth Busters - 3 Common Misconceptions
Quick: do you think dynamic blocks create multiple separate resources? Commit to yes or no.
Common Belief:Dynamic blocks create multiple independent resources like for_each does.
Tap to reveal reality
Reality:Dynamic blocks only create multiple nested blocks inside a single resource, not separate resources.
Why it matters:Confusing this leads to wrong resource management and unexpected Terraform state behavior.
Quick: do you think for_each can be used inside nested blocks? Commit to yes or no.
Common Belief:for_each can be used inside nested blocks to repeat them dynamically.
Tap to reveal reality
Reality:for_each cannot be used inside nested blocks; dynamic blocks are needed for that purpose.
Why it matters:Trying to use for_each inside nested blocks causes syntax errors and confusion.
Quick: do you think using many for_each resources always improves performance? Commit to yes or no.
Common Belief:Using for_each to create many resources always makes Terraform faster and more efficient.
Tap to reveal reality
Reality:Creating many resources with for_each can slow down Terraform plans and state operations due to increased state size.
Why it matters:Ignoring this can cause slow Terraform runs and harder state management in large projects.
Expert Zone
1
Dynamic blocks can include complex expressions and conditionals to finely control nested block creation, which is often overlooked.
2
for_each resource instances have independent lifecycle and state, enabling targeted updates and deletions, unlike nested blocks inside one resource.
3
Using dynamic blocks can reduce state size but may complicate change detection if nested blocks change frequently.
When NOT to use
Avoid dynamic blocks when you need to manage each repeated item as a separate resource with its own lifecycle, dependencies, or permissions. Instead, use for_each. Conversely, avoid for_each when the provider requires nested blocks inside a single resource, as dynamic blocks are the only option.
Production Patterns
In real-world Terraform projects, for_each is commonly used to create multiple servers, databases, or network interfaces. Dynamic blocks are used for repeating firewall rules, tags, or complex nested configurations inside a resource. Combining both allows flexible, maintainable infrastructure code that scales well.
Connections
Software Design Patterns
Dynamic blocks and for_each relate to the 'Factory' and 'Composite' patterns in software design.
Understanding these design patterns helps grasp how Terraform creates multiple objects (resources) or nested parts (blocks) dynamically, improving code reuse and organization.
Database Normalization
for_each is like creating separate tables (resources) for each entity, while dynamic blocks are like adding multiple columns or rows inside one table (nested blocks).
This analogy clarifies when to separate data/entities versus grouping related data inside one structure, similar to Terraform resource design.
Project Management Task Breakdown
for_each is like assigning individual tasks to team members, while dynamic blocks are like listing subtasks inside one main task.
This connection shows how breaking work into independent units or nested details parallels Terraform's resource and block repetition.
Common Pitfalls
#1Trying to use for_each inside a nested block to repeat it.
Wrong approach:resource "aws_security_group" "example" { name = "example" ingress { for_each = var.rules from_port = ingress.value.from_port to_port = ingress.value.to_port protocol = ingress.value.protocol } }
Correct approach:resource "aws_security_group" "example" { name = "example" dynamic "ingress" { for_each = var.rules content { from_port = ingress.value.from_port to_port = ingress.value.to_port protocol = ingress.value.protocol } } }
Root cause:Misunderstanding that for_each cannot be used directly inside nested blocks; dynamic blocks are required.
#2Using dynamic blocks to create multiple independent resources.
Wrong approach:resource "aws_instance" "example" { dynamic "instance" { for_each = var.instances content { ami = instance.value.ami instance_type = instance.value.type } } }
Correct approach:resource "aws_instance" "example" { for_each = var.instances ami = each.value.ami instance_type = each.value.type }
Root cause:Confusing dynamic blocks (for nested blocks) with for_each (for multiple resources).
#3Creating too many resources with for_each causing slow Terraform runs.
Wrong approach:resource "aws_security_group_rule" "example" { for_each = var.rules type = each.value.type from_port = each.value.from_port to_port = each.value.to_port protocol = each.value.protocol security_group_id = aws_security_group.example.id }
Correct approach:resource "aws_security_group" "example" { dynamic "ingress" { for_each = var.rules content { from_port = ingress.value.from_port to_port = ingress.value.to_port protocol = ingress.value.protocol } } }
Root cause:Not considering state size and plan performance when creating many separate resources instead of nested blocks.
Key Takeaways
Dynamic blocks repeat nested blocks inside a single resource, while for_each creates multiple separate resource instances.
Use for_each when you need independent resources with separate lifecycles; use dynamic blocks to repeat nested configuration inside one resource.
Dynamic blocks support conditional logic to create flexible nested blocks based on input data.
Choosing between for_each and dynamic blocks affects Terraform state size, plan speed, and resource management.
Understanding these tools helps write clean, maintainable, and scalable Terraform infrastructure code.