DEV Community

Bartłomiej Danek
Bartłomiej Danek

Posted on • Originally published at bard.sh

Terraform dynamic blocks

dynamic blocks

dynamic generates repeated nested blocks from a variable - avoids copy-pasting the same block for each item.

variable "ingress_rules" {
  default = [
    { port = 80,  protocol = "tcp", cidr = "0.0.0.0/0" },
    { port = 443, protocol = "tcp", cidr = "0.0.0.0/0" },
    { port = 22,  protocol = "tcp", cidr = "10.0.0.0/8" },
  ]
}

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

  dynamic "ingress" {
    for_each = var.ingress_rules
    content {
      from_port   = ingress.value.port
      to_port     = ingress.value.port
      protocol    = ingress.value.protocol
      cidr_blocks = [ingress.value.cidr]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

iterator name

By default the iterator is the block label (ingress above). Override it with iterator:

dynamic "ingress" {
  for_each = var.ingress_rules
  iterator = rule
  content {
    from_port = rule.value.port
    to_port   = rule.value.port
    protocol  = rule.value.protocol
  }
}
Enter fullscreen mode Exit fullscreen mode

conditional block

To make a block optional, pass an empty list or a one-element list:

variable "enable_logging" {
  default = true
}

resource "aws_s3_bucket" "main" {
  bucket = "my-bucket"

  dynamic "logging" {
    for_each = var.enable_logging ? [1] : []
    content {
      target_bucket = "my-logs-bucket"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

nested dynamic blocks

dynamic "rule" {
  for_each = var.rules
  content {
    action = rule.value.action

    dynamic "condition" {
      for_each = rule.value.conditions
      content {
        field  = condition.value.field
        values = condition.value.values
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Originally published at https://bard.sh/posts/terraform_dynamic_blocks/

Top comments (0)