2022-10-09

For-Each and Dynamic Blocks in Terraform

Overview of For-Each and Dynamic Blocks

One of the key features of Terraform is its ability to use for-each and dynamic blocks to create multiple instances of resources or modules in a single block of code.

For-each is a built-in function in Terraform that allows you to iterate over a list of values and create multiple instances of a resource or module. For example, if you wanted to create multiple AWS EC2 instances, you could use the for-each function to iterate over a list of instance names and create an instance for each name in the list.

Dynamic blocks, on the other hand, allow you to create multiple instances of a resource or module based on a dynamic configuration. This means that you can use dynamic blocks to create resources or modules based on input from variables or other resources. For example, you could use a dynamic block to create multiple subnets in AWS based on the number of availability zones in a given region.

Both for-each and dynamic blocks provide developers and operations teams with powerful tools for managing infrastructure resources at scale. By enabling the creation of multiple instances of resources or modules in a single block of code, these features help to simplify the process of managing large, complex infrastructure environments.

For-Each

The for-each function allows you to iterate over a list of values and create multiple instances of a resource or module based on those values. This can be useful when you need to create multiple instances of the same resource or module, but with different attributes or configurations.

The for-each function takes a map or a list as its input, and iterates over each element in the map or list. For each iteration, it creates a new instance of the resource or module, using the value of the current iteration as the input for any configurable attributes.

The syntax for using for-each in Terraform is as follows:

resource "<resource_type>" "<resource_name>" {
  for_each = <map_or_list>
  <attribute_1> = <value_1>
  <attribute_2> = <value_2>
  ...
}

In this syntax, <resource_type> is the type of resource you want to create, <resource_name> is the name of the resource, <map_or_list> is the map or list you want to iterate over, and <attribute_1>, <attribute_2>, etc. are the configurable attributes for the resource.

Here is an example of using for-each to create multiple AWS EC2 instances:

resource "aws_instance" "ec2_instances" {
  for_each = {
    "instance-1" = "ami-0c55b159cbfafe1f0"
    "instance-2" = "ami-0c55b159cbfafe1f0"
    "instance-3" = "ami-0c55b159cbfafe1f0"
  }

  instance_type = "t2.micro"
  ami = each.value
}

In this example, we are creating three instances of the aws_instance resource, using the same AMI but different instance names. The for-each function iterates over a map containing the instance names and the corresponding AMI IDs. The instance_type attribute is set to t2.micro for all instances, while the ami attribute is set to the value of the current iteration using the each.value syntax.

Dynamic Blocks

Dynamic blocks allow you to create multiple instances of a resource or module based on a dynamic configuration. This can be useful when you need to create resources or modules based on input from variables or other resources, such as the number of availability zones in an AWS region.

Dynamic blocks are defined using a special syntax that allows you to specify the resource or module type, along with a dynamic block configuration that defines the attributes for each instance of the resource or module. This configuration is evaluated dynamically at runtime, allowing you to create resources or modules based on input from variables or other resources.

The syntax for using dynamic blocks in Terraform is as follows:

resource "<resource_type>" "<resource_name>" {
  dynamic "<block_name>" {
    for_each = <expression>

    <attribute_1> = <value_1>
    <attribute_2> = <value_2>
    ...
  }
}

In this syntax, <resource_type> is the type of resource you want to create, <resource_name> is the name of the resource, <block_name> is the name of the dynamic block, and <expression> is the expression that defines the number of instances to create. The <attribute_1>, <attribute_2>, etc. are the configurable attributes for each instance of the resource.

Here is an example of using dynamic blocks to create multiple AWS subnets based on the number of availability zones in a region:

resource "aws_subnet" "subnet" {
  dynamic "subnet" {
    for_each = var.availability_zones

    content {
      cidr_block = cidrsubnet(var.vpc_cidr_block, 8, each.key)
      availability_zone = each.value
    }
  }
}

In this example, we are using dynamic blocks to create multiple AWS subnets, one for each availability zone in the region. The for_each expression is a variable called availability_zones that contains a list of availability zones in the region. The dynamic block configuration specifies the attributes for each subnet, including the cidr_block and availability_zone attributes.

Dynamic blocks enable you to create multiple instances of resources or modules based on dynamic input, making it easier to manage complex infrastructure environments. By using dynamic blocks effectively, you can create scalable, maintainable, and efficient Terraform code that can adapt to changing infrastructure requirements.

Differences between For-Each and Dynamic Blocks

Both for-each and dynamic blocks enable the creation of multiple instances of resources or modules in a single block of code, but there are some key differences between them.

Comparison of For-Each and Dynamic Blocks

For-each is a built-in function in Terraform that enables you to create multiple instances of a resource or module based on a list or map of values. For-each is best suited for situations where you need to create a fixed number of instances of a resource or module, but with different attributes or configurations. For-each is a static construct, meaning that the number of instances is defined at the time of code creation and cannot be changed at runtime.

Dynamic blocks, on the other hand, enable you to create multiple instances of a resource or module based on a dynamic configuration. Dynamic blocks are best suited for situations where the number of instances depends on external input, such as the number of availability zones in an AWS region. Dynamic blocks are evaluated at runtime, allowing you to create resources or modules based on input from variables or other resources.

Use Cases for For-Each and Dynamic Blocks

For-each and dynamic blocks have different use cases in Terraform, and are best suited for different situations.

Use cases for for-each include:

  • Creating multiple instances of a resource or module with different attributes or configurations.
  • Creating a fixed number of instances of a resource or module.
  • Simplifying the code by avoiding the need for multiple copies of a resource or module with similar configurations.

Use cases for dynamic blocks include:

  • Creating multiple instances of a resource or module based on a dynamic configuration, such as the number of availability zones in an AWS region.
  • Creating resources or modules based on input from variables or other resources.
  • Enabling the code to adapt to changing infrastructure requirements.

In general, for-each is best suited for situations where the number of instances is known at the time of code creation, while dynamic blocks are best suited for situations where the number of instances depends on external input. By using for-each and dynamic blocks effectively, you can create scalable, maintainable, and efficient Terraform code that can adapt to changing infrastructure requirements.

References

https://www.middlewareinventory.com/blog/terraform-for-each-examples/
https://brendanthompson.com/posts/2022/11/terraform-dynamic-blocks

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!