Terraform Tutorial · Terraform Language · Lesson 15 of 25

Terraform Dynamic Blocks

Generate repeated nested blocks, such as security group rules, from a list or map with dynamic blocks.

The problem

Some resources take repeated nested blocks, for example security group ingress rules. Writing them out by hand is repetitive, and you can't use for_each on a nested block directly.

dynamic blocks

variable "ingress_ports" {
  default = [80, 443]
}

resource "aws_security_group" "web" {
  name = "web"

  dynamic "ingress" {
    for_each = var.ingress_ports
    content {
      from_port   = ingress.value
      to_port     = ingress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
}

Inside content, the iterator is named after the block (ingress.value, ingress.key).

The rules a dynamic block would generate
# The same data shaping a dynamic block does, shown as an output:
variable "ingress_ports" {
  default = [80, 443]
}

output "rules" {
  value = [for p in var.ingress_ports : {
    from_port = p
    to_port   = p
    protocol  = "tcp"
  }]
}

Output

rules = [
  {
    "from_port" = 80
    "protocol" = "tcp"
    "to_port" = 80
  },
  {
    "from_port" = 443
    "protocol" = "tcp"
    "to_port" = 443
  },
]

Run this on your computer — see “Get Started” for setup.

Use dynamic blocks sparingly: they make configurations harder to read. They are best inside reusable modules.

Test yourself

Inside dynamic "ingress" { … }, how do you read the current item?

  1. each.value
  2. ingress.value
  3. count.index
  4. self.value
Show answer

Answer: ingress.value