Hello!

In this article, I will show how to use the dynamic block on the example of creating an AWS Security Group.

To begin with, I will create a Security Group without using the dynamic block. In this example, each rule is described in a separate ingress block.

resource "aws_security_group" "test_sg" {
  name        = "test-sg"
  description = "allow traffic to web app"
  vpc_id      = "vcp-123"

  ingress {
    from_port = 8082
    to_port   = 8082
    protocol  = "tcp"

    cidr_blocks = [
      "0.0.0.0/0"
    ]
  }

  ingress {
    from_port = 3000
    to_port   = 3000
    protocol  = "tcp"
    cidr_blocks = [
      "0.0.0.0/0"
    ]
  }

  ingress {
    from_port = 80
    to_port   = 80
    protocol  = "tcp"
    cidr_blocks = [
      "0.0.0.0/0"
    ]
  }
  ingress {
    from_port = 22
    to_port   = 22
    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"
    ]
  }

  ingress {
    from_port = 8080
    to_port   = 8080
    protocol  = "tcp"
    cidr_blocks = [
      "0.0.0.0/0"
    ]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "test-sg"
  }
}

This code can be significantly shortened with a single dynamic block. In this case, the dynamic block works as a for loop. In for_each parameter I describe a list of values that terraform should loop through. And in the content block, I use the values from the list in loop. And thus the code was reduced from 70 lines of code to 20.

resource "aws_security_group" "test_sg" {
  name        = "test-sg"
  description = "allow traffic to web app"
  vpc_id      = "vcp-123"

  dynamic "ingress" {
    for_each = [8080, 443, 22, 80, 3000, 8082]
    content {
      from_port = ingress.value
      to_port   = ingress.value
      protocol  = "tcp"
      cidr_blocks = [
        "0.0.0.0/0"
      ]
    }
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

Video