OpsCanary
terraformmodulesPractitioner

Mastering Dynamic Blocks in Terraform Modules

5 min read HashiCorp DocsApr 28, 2026
Share
PractitionerHands-on experience recommended

Dynamic blocks exist to address the need for flexibility in Terraform configurations, particularly when dealing with nested structures. They allow you to iterate over complex values and generate nested blocks dynamically, which can significantly reduce redundancy and improve readability in your Terraform modules.

A dynamic block acts similarly to a for expression but produces nested blocks instead of complex typed values. You define a dynamic block using the for_each argument, which accepts any collection or structural value. Inside the block, you can specify an optional iterator to represent the current element, and a content block to define the body of each generated block. This means you can create configurations that adapt based on input variables, making your modules much more versatile.

In production, be cautious with dynamic blocks. Overusing them can lead to configurations that are hard to read and maintain. They should primarily be used when you need to abstract complexity and create a clean interface for reusable modules. Additionally, remember that you cannot use dynamic blocks to generate meta-argument blocks like lifecycle and provisioner blocks, as Terraform processes these before evaluating expressions.

Key takeaways

  • Utilize dynamic blocks to generate nested blocks based on complex values.
  • Implement the `for_each` argument to iterate over collections in your configurations.
  • Define an optional `iterator` to represent the current element for clarity.
  • Use dynamic blocks sparingly to maintain readability in your Terraform code.
  • Avoid using dynamic blocks for meta-argument blocks like lifecycle and provisioner.

Why it matters

Dynamic blocks can significantly streamline your Terraform configurations, reducing duplication and enhancing maintainability. This leads to faster deployments and fewer errors in production environments.

Code examples

terraform
resource"aws_elastic_beanstalk_environment""tfenvtest"{name="tf-test-name"application=aws_elastic_beanstalk_application.tftest.namesolution_stack_name="64bit Amazon Linux 2018.03 v2.11.4 running Go 1.12.6"dynamic"setting"{for_each=var.settingscontent{namespace=setting.value["namespace"]name=setting.value["name"]value=setting.value["value"]}}}
terraform
variable"load_balancer_origin_groups"{type=map(object({origins=set(object({hostname=string}))}))}
terraform
dynamic"origin_group"{for_each=var.load_balancer_origin_groupscontent{name=origin_group.keydynamic"origin"{for_each=origin_group.value.originscontent{hostname=origin.value.hostname}}}}

When NOT to use this

It is not possible to generate meta-argument blocks such as lifecycle and provisioner blocks, since Terraform must process these before it is safe to evaluate expressions.

Want the complete reference?

Read official docs

Test what you just learned

Quiz questions written from this article

Take the quiz →

Get the daily digest

One email. 5 articles. Every morning.

No spam. Unsubscribe anytime.