0
0
Terraformcloud~5 mins

Why dynamic blocks reduce repetition in Terraform - Why It Works

Choose your learning style9 modes available
Introduction
When you write infrastructure code, you often repeat similar blocks for multiple items. Dynamic blocks let you write one block that repeats automatically, saving time and reducing errors.
When you need to create multiple similar resources or nested blocks with small differences.
When you want to avoid copying and pasting the same code many times.
When your infrastructure configuration depends on a list or map of values.
When you want your code to be easier to update and maintain.
When you want to reduce mistakes caused by manual repetition.
Config File - main.tf
main.tf
variable "security_group_rules" {
  type = list(object({
    type        = string
    from_port   = number
    to_port     = number
    protocol    = string
    cidr_blocks = list(string)
  }))
  default = [
    {
      type        = "ingress"
      from_port   = 80
      to_port     = 80
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    },
    {
      type        = "ingress"
      from_port   = 443
      to_port     = 443
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  ]
}

resource "aws_security_group" "example" {
  name        = "example-sg"
  description = "Example security group"

  dynamic "ingress" {
    for_each = [for rule in var.security_group_rules : 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
    }
  }
}

This Terraform file defines a variable with a list of security group rules. The aws_security_group resource uses a dynamic block to create multiple ingress rules automatically from the list. This avoids writing each rule manually.

The dynamic block loops over the rules and inserts the content block for each one, making the code shorter and easier to maintain.

Commands
This command initializes the Terraform working directory. It downloads the AWS provider plugin and prepares Terraform to run.
Terminal
terraform init
Expected OutputExpected
Initializing the backend... Initializing provider plugins... - Finding latest version of hashicorp/aws... - Installing hashicorp/aws v4.0.0... - Installed hashicorp/aws v4.0.0 (signed by HashiCorp) Terraform has been successfully initialized!
This command shows what Terraform will do based on the configuration. It previews the creation of the security group with multiple ingress rules from the dynamic block.
Terminal
terraform plan
Expected OutputExpected
An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_security_group.example will be created + resource "aws_security_group" "example" { + description = "Example security group" + id = (known after apply) + name = "example-sg" + ingress { + cidr_blocks = ["0.0.0.0/0"] + from_port = 80 + protocol = "tcp" + to_port = 80 } + ingress { + cidr_blocks = ["0.0.0.0/0"] + from_port = 443 + protocol = "tcp" + to_port = 443 } } Plan: 1 to add, 0 to change, 0 to destroy.
This command applies the configuration and creates the security group with the ingress rules. The -auto-approve flag skips manual confirmation.
Terminal
terraform apply -auto-approve
Expected OutputExpected
aws_security_group.example: Creating... aws_security_group.example: Creation complete after 2s [id=sg-0123456789abcdef0] Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
-auto-approve - Automatically approve the apply without asking for confirmation
This command displays the current state of the created resources, showing the security group with its dynamically created ingress rules.
Terminal
terraform show
Expected OutputExpected
aws_security_group.example: id = sg-0123456789abcdef0 name = example-sg description = Example security group ingress { from_port = 80 to_port = 80 protocol = tcp cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = tcp cidr_blocks = ["0.0.0.0/0"] }
Key Concept

If you remember nothing else from this pattern, remember: dynamic blocks let you write one block that repeats for many items, reducing copy-paste and making your code cleaner.

Common Mistakes
Writing multiple static blocks instead of using a dynamic block
This causes repetitive code that is hard to update and prone to errors.
Use a dynamic block with for_each to generate repeated blocks automatically from a list or map.
Using dynamic blocks without filtering the list properly
Terraform may try to create blocks for unwanted items, causing errors or unexpected resources.
Filter the list in for_each to include only relevant items for the dynamic block.
Summary
Dynamic blocks in Terraform let you generate repeated nested blocks from a list or map.
They reduce manual repetition and make your code easier to maintain and update.
Use terraform init, plan, apply, and show commands to deploy and verify your dynamic block configuration.