0
0
TerraformHow-ToBeginner · 4 min read

How to Use Dynamic Block in Terraform: Syntax and Example

Use the dynamic block in Terraform to create repeated nested blocks dynamically based on a list or map. It requires specifying a for_each expression and a content block that defines the nested block structure.
📐

Syntax

The dynamic block lets you generate multiple nested blocks dynamically. It has three main parts:

  • for_each: A list or map to loop over.
  • content: Defines the nested block structure to repeat.
  • each: Represents the current item in the loop inside content.
terraform
dynamic "block_name" {
  for_each = var.items
  content {
    attribute = each.value
  }
}
💻

Example

This example shows how to create multiple ingress rules in an AWS security group using a dynamic block. The for_each loops over a list of rules, and each rule creates an ingress block with the specified attributes.

terraform
variable "ingress_rules" {
  type = list(object({
    from_port   = number
    to_port     = number
    protocol    = string
    cidr_blocks = list(string)
  }))
  default = [
    { from_port = 80, to_port = 80, protocol = "tcp", cidr_blocks = ["0.0.0.0/0"] },
    { from_port = 443, to_port = 443, protocol = "tcp", cidr_blocks = ["0.0.0.0/0"] }
  ]
}

resource "aws_security_group" "example" {
  name = "example-sg"

  dynamic "ingress" {
    for_each = var.ingress_rules
    content {
      from_port   = ingress.value.from_port
      to_port     = ingress.value.to_port
      protocol    = ingress.value.protocol
      cidr_blocks = ingress.value.cidr_blocks
    }
  }
}
Output
Terraform will create an AWS security group with two ingress rules: one for port 80 and one for port 443, both allowing TCP traffic from any IP.
⚠️

Common Pitfalls

Common mistakes when using dynamic blocks include:

  • Using each.value inside content but forgetting to match the label used in dynamic "label" (e.g., use ingress.value if the label is ingress).
  • Trying to use dynamic blocks for simple repeated attributes instead of nested blocks.
  • Not providing a proper iterable for for_each, causing errors.

Wrong example:

dynamic "ingress" {
  for_each = var.ingress_rules
  content {
    from_port = each.value.from_port  # Incorrect: should be ingress.value.from_port
  }
}

Right example:

dynamic "ingress" {
  for_each = var.ingress_rules
  content {
    from_port = ingress.value.from_port
  }
}
📊

Quick Reference

Tips for using dynamic blocks:

  • Use dynamic only for nested blocks, not simple attributes.
  • Inside content, use the label name (e.g., ingress.value) to access the current item.
  • for_each must be a list or map.
  • Combine with variables to create flexible, reusable configurations.

Key Takeaways

Use dynamic blocks to create repeated nested blocks based on a list or map.
Inside the content block, access the current item with the dynamic block label and .value.
for_each must be a valid iterable like a list or map.
Avoid using dynamic blocks for simple repeated attributes; use them only for nested blocks.
Dynamic blocks help make Terraform configurations flexible and reusable.