How to use Terraform Dynamic blocks?



Terraform Dynamic Block is important when you want to create multiple resources inside of similar types, so instead of copy and pasting the same terraform configuration in the terraform file does not make sense and it is not feasible if you need to create hundreds of resources using terraform.

If we describe terraform dynamic block in simple words then it is for loop which is going to iterate over and will help you to create a dynamic resource. With the help of dynamic blocks you can create nested repeatable blocks such as settings, ingress rules etc...

If this is the first time you are trying to learn to terraform then I would highly recommend reading my Getting started guide on Terraform -

  1. Install terraform on MacOS, Windows, and Ubuntu

  2. How to setup Virtual machine on Google Cloud Platform

  3. How to setup terraform EC2 instance

In this post, we are going to see the examples and how to implement dynamic blocks.

Table of Content

  1. Syntax of Dynamic Block
  2. How to create your first terraform dynamic block
  3. Best practices for dynamic block



1. Syntax of Dynamic Block

As we said dynamic block is more or less another way to implement for loop. Here are few facts about dynamic block which you should keep in mind -

  1. Collections - You need to have collections .e.g. - list, map, set
  2. Iterator - To create a dynamic block you need to define an iterator.
  3. Content - Content is something onto which you wanna iterate.

Here is the syntax of dynamic block -

Terraform dynamic block syntax



2. How to create your first terraform dynamic block

Before we implement our first terraform dynamic block let's first see an example without dynamic block.

In this example, we are going to create two ingress rules for the aws_security_group. Both ingress rules are exactly the same apart from the port numbers .i.e. - 80 and 443. So if we do not use dynamic block then we need to create two ingress rules blocks inside the terraform file.

 1resource "aws_security_group" "main" {
 2   name   = "resource_without_dynamic_block"
 3   vpc_id = data.aws_vpc.main.id
 4
 5   ingress {
 6      description = "ingress_rule_1"
 7      from_port   = 443
 8      to_port     = 443
 9      protocol    = "tcp"
10      cidr_blocks = ["0.0.0.0/0"]
11   }
12   
13   ingress {
14      description = "ingress_rule_2"
15      from_port   = 80
16      to_port     = 80
17      protocol    = "tcp"
18      cidr_blocks = ["0.0.0.0/0"]
19   }
20
21   tags = {
22      Name = "AWS security group non-dynamic block"
23   }
24}

The same terraform file can be improved by using dynamic block, now look at the following terraform file -

 1locals {
 2   ingress_rules = [{
 3      port        = 443
 4      description = "Ingress rules for port 443"
 5   },
 6   {
 7      port        = 80
 8      description = "Ingree rules for port 80"
 9   }]
10}
11
12resource "aws_security_group" "main" {
13   name   = "resource_with_dynamic_block"
14   vpc_id = data.aws_vpc.main.id
15
16   dynamic "ingress" {
17      for_each = local.ingress_rules
18
19      content {
20         description = ingress.value.description
21         from_port   = ingress.value.port
22         to_port     = ingress.value.port
23         protocol    = "tcp"
24         cidr_blocks = ["0.0.0.0/0"]
25      }
26   }
27
28   tags = {
29      Name = "AWS security group dynamic block"
30   }
31}

Now you can imagine, if you need to define more than 2 ingress rules then using dynamic block can help you to reduce the line of code inside your terraform file.

Ingress rules are just an example but the same concept can be applied to another resource block.



3. Best practices for dynamic block

  1. Do not overuse the dynamic block when it is not necessary
  2. Multiple nested dynamic blocks should be avoided otherwise it might cause you trouble in debugging and troubleshooting.
  3. If the dynamic block is getting too complex inside your terraform file then it's better to use terraform module.



Read More - Terragrunt -

  1. How to use Terragrunt?

Posts in this Series