liveBook · Manning

Dynamic block

As explained in Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu

A dynamic block is a Terraform language construct that generates zero or more nested configuration blocks from a collection of values.

A dynamic block generates zero or more repeated nested Terraform blocks from a collection, making reusable resources adaptable to changing configuration needs such as network access rules. section 4.10

The construct names the nested block, iterates with for_each, and places generated arguments inside content. Each iteration exposes a keyword named after that block, such as ingress.value; the syntax also supports nested dynamic blocks. section 4.10

Listing 4.46 dynamic block
variable "security_group_rules" {
  type = list(object({
    description = string,
    from_port   = number,
    to_port     = number
    protocol    = string
    cidr_blocks = list(string)
  }))
}
 
resource "aws_security_group" "main" {
  name        = "${var.name}-sg"
  description = "The security group for an AWS Instance."
  vpc_id      = var.vpc_id
 
  dynamic "ingress" {                                               #1
    for_each = var.security_group_rules                             #2
 
    content {
      description = ingress.value.description                       #3
      from_port   = ingress.value.from_port                         #3
      to_port     = ingress.value.to_port                           #3
      protocol    = ingress.value.protocol                          #3
      cidr_blocks = ingress.value.cidr_blocks                       #3
    }
  }
 
  ingress {                                                         #4
    description = "HTTPS"
    from_port   = 443
    to_port     = 443
    protocol    = tcp
    cidr_blocks = ["0.0.0.0/0"]
  }
}

Use the security-group example to connect a typed collection of rule objects with generated ingress blocks and their per-item values. section 4.10

Toggle one nested block

Set for_each to var.enable_public_https ? ["placeholder"] : []. The empty list produces no ingress block; the one-item list produces a single HTTPS ingress block, even though the placeholder value is unused. section 4.10

Use dynamic blocks deliberately:

  • Use them when the number of nested blocks depends on input values or when a reusable module cannot define every possible subblock in advance. section 4.10
  • Test zero, one, and many generated blocks, concentrating on configuration logic rather than provider behavior. section 9.1.1
Listing 4.47 dynamic block toggle
resource "aws_security_group" "dynamic" {
  name        = "${var.name}-sg"
  description = "The security group for an AWS Instance."
  vpc_id      = var.vpc_id
 
  dynamic "ingress" {                                              #1
    for_each = var.enable_public_https ? ["placeholder"] : []      #2
 #B
    content {
      description = "Enable global access to port 443 (HTTPS)."
      from_port   = 443                                            #3
      to_port     = 443
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]                                  #4
    }
  }
 
  egress {                                                         #5
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }
}

Use the toggle listing to inspect conditional collection selection and the resulting public HTTPS ingress rule. section 4.10

How Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu covers it

How deep it goes
Explains labels, for_each, content, generated iteration keywords, nesting, and conditional toggling, but not provider internals.
Examples
Uses AWS security-group ingress rules, optional global HTTPS access, placeholder collections, and zero-one-many testing cases.
What it assumes
Assumes familiarity with Terraform resources, HCL arguments and subblocks, collections, for_each, and conditional expressions.
What you can do after
Build it from scratch by generating configurable nested blocks and testing their zero, one, and many-item behaviors.
How it connects
Connects dynamic blocks with Terraform expressions, for_each, conditional expressions, modules, nested blocks, and testing.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu. The section links point to the parts of the book it draws on.