What You Need To Know About Terraform Dynamic Block Syntax 

Terraform Dynamic Block Syntax 

Table of Contents

Get up to 50% off now

Become a partner with CyberPanel and gain access to an incredible offer of up to 50% off on CyberPanel add-ons. Plus, as a partner, you’ll also benefit from comprehensive marketing support and a whole lot more. Join us on this journey today!

Repetitive configurations can quickly clutter your code when you’re managing cloud infrastructure with Terraform. But to be fair, it’s not always your team’s fault, Terraform configuration files are becoming harder to manage and understand.

Terraform Dynamic block helps create reusable nested blocks using loops like for_each. They make your infrastructure code more efficient, cleaner, and scalable. Whether dealing with complex modules or wanting to minimize hardcoding, learning to use dynamic blocks is an essential skill in Terraform.

This is a quick tutorial on everything about Terraform Dynamic Block. Let’s Learn Along!

What Is a Terraform Dynamic Block?

what-is-terraform-dynamic-block-full guide-2025

By creating numerous nested blocks, Terraform dynamic blocks—a unique sort of Terraform block—offer the capability of a for expression.

It is frequently necessary to establish infrastructure resources that are identical or comparable. Multiple virtual server instances on a cloud platform like AWS or Azure Terraform, are a common use case. Terraform offers routines like for_each and count to make the deployment of these resources easier and eliminate the need for lengthy blocks of repetitive code.

Teams can also have to set up several duplicate elements in a resource. To eliminate the requirement for numerous duplicate “blocks” of Terraform code, dynamic blocks are utilized inside an infrastructure resource in conjunction with a for_each function.

Tech Delivered to Your Inbox!

Get exclusive access to all things tech-savvy, and be the first to receive 

the latest updates directly in your inbox.

Here are some scenarios where dynamic blocks are useful:

  • Creating several AWS subnets: If you need to set up subnets across various availability zones, instead of writing individual blocks for each subnet, you can utilize a dynamic block to loop through a list of availability zones and create a subnet for each one.
  • Configuring security group rules: When dealing with numerous security group rules, dynamic blocks assist in defining and organizing them in a more compact manner.
  • Rather than writing each rule individually, you can use a dynamic block to iterate over a list of rules, making the configuration easier.
  • Provisioning multiple EC2 instances: If you require several EC2 instances with similar settings but different characteristics (such as tags or instance types), dynamic blocks enable you to manage this effectively.

A Terraform dynamic block offers the following main advantages:

  • Speed: The infrastructure can be deployed more rapidly when the code is simplified, both during development and execution.
  • Clarity – code written with dynamic blocks is significantly easier to read and comprehend than code written in several blocks of repetitive code.
  • Reuse: It can be challenging and time-consuming to copy, paste, and edit lengthy code blocks. To make this process go more quickly, combine variables and parameters with dynamic blocks.
  • Reliability is associated with clarity and reusability; simple, readable code is less likely to include errors.

Dynamic Block Syntax Example

Dynamic Block Syntax in Terraform allows for the generation of various configurations depending on input values. The label indicates the type of dynamic block to be created. The for_each statement iterates over a list or map given by var.iterable_variable, producing a block for each element. The iterator serves as an optional name for the current item in the iteration. The content block holds the configuration specifics for each created block.

dynamic "label" {<br>  for_each = var.iterable_variable<br>  iterator = iterator_name # Optional, defaults to label<br><br>  content {<br>    # Configuration details for each iteration<br>    attribute = iterator_name.value<br>  }<br>}

Applications of Dynamic Block Syntax in the Real World

  • A data block downloads existing EC2 instances in a real-world scenario and generates a local variable to store the instance IDs.
  • Based on the instance IDs of EC2 instances, a dynamic block applies particular EBS configurations to them.
  • By repeating over the instance IDs, various EBS volumes are dynamically attached to the designated instances. This method guarantees that every instance obtains the appropriate EBS volume settings without the need for further code.

Here is an example of how our resource block will look:

resource "aws_instance" "dynamic_instance" {
  for_each = {
    for instance_id in local.instance_ids :
    instance_id => instance_id
  }

  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  tags = {
    Name = each.key
  }

  dynamic "ebs_block_device" {
    for_each = [
      for id in local.instance_ids : id
      if id == "i-0d5933a76d45a6aee"
    ]
    content {
      device_name = "/dev/sdh"
      volume_size = 10
      encrypted   = true
    }
  }

  dynamic "ebs_block_device" {
    for_each = [
      for id in local.instance_ids : id
      if id == "i-095aff1e2acc82958"
    ]
    content {
      device_name = "/dev/sdh"
      volume_size = 20
      encrypted   = true
    }
  }
}

Required Attribute of Dynamic Block in Terraform

Essential Features of a Dynamic Block

For proper functionality, a dynamic block must include:

  • for_each: Loops through a list or map.
  • content: The specific content of the block for each iteration.

Additionally, there are optional attributes that can be beneficial:

  • iterator: Enables you to change the name of the loop variable from the default ‘each’.

Example:

variable "security_groups" {
  default = ["sg-123", "sg-456"]
}

resource "aws_instance" "web" {
  ami           = "ami-abc123"
  instance_type = "t2.micro"

  dynamic "security_group" {
    for_each = var.security_groups
    content {
      id = security_group.value
    }
  }
}

How to Use the Terraform Import Block with Dynamic Blocks

Utilizing Resource Blocks with Terraform Dynamic Block

Instead of having many separate entrance blocks, the example below dynamically generates the repeating ingress blocks using Terraform dynamic blocks.

Enhance Your CyerPanel Experience Today!
Discover a world of enhanced features and show your support for our ongoing development with CyberPanel add-ons. Elevate your experience today!

# variables.tf
variable "settings" {
  type = list(object({
    description = string
    port        = number
  }))
  default = [
    {
      description = "Allows SSH access"
      port        = 22
    },
    {
      description = "Allows HTTP traffic"
      port        = 80
    },
    {
      description = "Allows HTTPS traffic"
      port        = 443
    }
  ]
}

# main.tf
resource "aws_vpc" "sandbox_vpc" {
  cidr_block       = "10.0.0.0/16"
  instance_tenancy = "default"

  tags = {
    Name = "sandbox_vpc"
  }
}

resource "aws_subnet" "sandbox_subnet" {
  vpc_id     = aws_vpc.sandbox_vpc.id
  cidr_block = "10.0.1.0/24"

  tags = {
    Name = "sandbox_subnet"
  }
}

resource "aws_security_group" "sandbox_sg" {
  name   = "sandbox_sg"
  vpc_id = aws_vpc.sandbox_vpc.id

  dynamic "ingress" {
    for_each = var.settings
    iterator = sandbox_sg_ingress

    content {
      description = sandbox_sg_ingress.value["description"]
      from_port   = sandbox_sg_ingress.value["port"]
      to_port     = sandbox_sg_ingress.value["port"]
      protocol    = "tcp"
      cidr_blocks = [aws_vpc.sandbox_vpc.cidr_block]
    }
  }

  tags = {
    Name = "sandbox_sg"
  }
}

Using a dynamic block in the configuration eliminates duplicate attributes, enhancing code maintainability. The optional iterator is now the name of the dynamic block, which means subnet.value.name should be used instead of item.value.name in the content block.

Recognizing the block that Terraform transferred

Terraform 1.1+ introduced Terraform moved blocks to refactor infrastructure safely. They notify Terraform of the relocation or renaming of a resource or module.

Syntax:

changed the value of

moved {<br>from = aws_instance.old<br>to = aws_instance.new<br>}

Using Dynamic Blocks:

Keep the block structure constant.

Use it when renaming a resource that has internally specified dynamic blocks.

Example 2: Using Terraform dynamic block in data blocks

In the following example, we use a dynamic block to filter AMIs in a data source based on specific tags. If there are any matches, these AMIs will be returned in a list that can be utilized later in our configuration code.

variable "ami_filters" {
  description = "A list of tag filters for finding AMIs"
  default = [
    {
      name   = "tag:Purpose"
      values = ["WebServer"]
    },
    {
      name   = "tag:Environment"
      values = ["Prod"]
    }
  ]
}

data "aws_ami" "custom_ami" {
  most_recent = true
  owners      = ["self"]

  dynamic "filter" {
    for_each = var.ami_filters
    content {
      name   = filter.value.name
      values = filter.value.values
    }
  }
}

Example 3: Setting up an AWS Security Group with Terraform dynamic blocks

There are two ways to define security group rules for AWS with Terraform:

1. Using the security group resource along with a specific security group rule resource.

2. Using just the security group resource (This is the older method and is not advised anymore).

In the first method, the code will look like this:

esource "aws_security_group" "this" {
 for_each = var.sg_params
 vpc_id   = each.value.vpc_id

 tags = {
   Name = each.key
 }
}

resource "aws_security_group_rule" "this" {
 for_each    = var.sg_rule_params
 type        = each.value.type
 from_port   = each.value.from_port
 to_port     = each.value.to_port
 protocol    = each.value.protocol
 cidr_blocks = each.value.cidr_blocks
 security_group_id = aws_security_group.this[each.value.sg_name].id
}

In the second case, using dynamic blocks within the security group would be the best approach.

resource "aws_security_group" "this" {
 for_each = var.sg_params
 vpc_id   = each.value.vpc_id

 tags = {
   Name = each.key
 }

 dynamic "ingress" {
   for_each = [for rule in each.value.sg_rule_params : rule if rule.type == "ingress"]
   content {
     from_port   = ingress.value.from_port
     to_port     = ingress.value.to_port
     protocol    = ingress.value.protocol
     cidr_blocks = ingress.value.cidr_blocks
   }
 }

 dynamic "egress" {
   for_each = [for rule in each.value.sg_rule_params : rule if rule.type == "egress"]
   content {
     from_port   = egress.value.from_port
     to_port     = egress.value.to_port
     protocol    = egress.value.protocol
     cidr_blocks = egress.value.cidr_blocks
   }
 }
}

The example uses two dynamic blocks for inbound and outbound traffic, with a single variable for security groups. However, AWS recommends against using aws_security_group for defining rules.

Tips for Troubleshooting Common Issues with a Terraform Dynamic Block:

Here are typical errors and how to resolve them:

  • 1. Missing for_each or content Block: Both are required in every dynamic block.
  • 2. Wrong Loop Type: for_each must be a map or list; avoid null values.
  • 3. Incorrect Iterator Usage: If using a custom iterator, make sure it’s properly referenced in the content.
  • 4. Dynamic Block on Unsupported Field: Some fields, like primitive attributes, do not allow dynamic blocks.

Conclusion: Is the Dynamic Block Right for Your Use Case?

Terraform Dynamic Block are undoubtedly the most powerful tools to create scalable, flexible infrastructure-as-code. They reduce readability, allowing you to work more efficiently, especially in Large environments.

While they can still be complex, learning basic troubleshooting tips allows you to tackle them easily. These tips help prevent redundant code by iterating over a list or map to create multiple instances of a nested configuration.

FAQ’s

Q1: What do dynamic blocks do in Terraform?
A Terraform dynamic block creates nested blocks in Terraform configuration files programmatically, based on lists or maps.

Q2: Can I use count within a dynamic block?
No, dynamic blocks only allow for_each. count is not allowed within dynamic blocks.

Q3: How to fix Terraform dynamic block errors?
Verify your code with terraform validate, inspect the data type of for_each, and verify the required attribute of Dynamic Block in Terraform, such as content.

Q4: Can dynamic blocks be used within modules?
Yes, dynamic blocks are commonly utilized within modules for creating conditional or repeatable nested blocks.

Q5: How do dynamic blocks relate to terraform import? When importing existing infrastructure, ensure that dynamic blocks accurately reflect the actual structure of the imported resource to avoid state mismatches.h


Areeba Nauman
Areeba is a Content Writer with expertise in web content and social media, she can simplify complex concepts to engage diverse audiences. Fueled by creativity and driven by results, she brings a unique perspective and a keen attention to detail to every project she undertakes with her creativity and passion for delivering impactful content strategies for success. Let's connect on Linkedin: https://www.linkedin.com/in/areeba-bhatti/
Unlock Benefits

Become a Community Member

SIMPLIFY SETUP, MAXIMIZE EFFICIENCY!
Setting up CyberPanel is a breeze. We’ll handle the installation so you can concentrate on your website. Start now for a secure, stable, and blazing-fast performance!