3 ways to use loops in Terraform (with examples)

Updated: February 3, 2024 By: Guest Contributor Post a comment

Introduction

Looping in Terraform allows for the dynamic creation of similar resources or the iteration over a set of values to apply configurations. This guide explores several looping techniques provided by Terraform, demonstrating their applications through examples.

Approach 1: Count Parameter

The count parameter is a traditional method to create multiple instances of a resource in Terraform. This parameter defines how many times a resource is created, based on the count’s numeric value.

  1. Define a resource in your Terraform configuration.
  2. Use the count parameter within the resource block.
  3. Refer to each instance with count.index when specifying resource attributes.

Example:

resource "aws_instance" "example" {
  count         = 3
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  tags = {
    Name = "ExampleInstance-${count.index}"
  }
}

Notes: Using the count parameter simplifies the creation of multiple instances but lacks flexibility in managing each instance individually. It’s best used when instances require similar configurations.

Approach 2: For_each Loop

Terraforms for_each loop iterates over a map or set of strings, creating one resource per item. This offers more control and flexibility compared to the count approach.

  1. Define a variable as a map or set representing the entities to manage.
  2. Implement the for_each loop within a resource block, referring to each item with each.key or each.value.

Example:

variable "instance_details" {
  type = map(object({
    ami           = string
    instance_type = string
  }))
}

resource "aws_instance" "example" {
  for_each = var.instance_details

  ami           = each.value.ami
  instance_type = each.value.instance_type
  tags = {
    Name = "Instance-${each.key}"
  }
}

Notes: The for_each loop provides a high degree of customization for each instance but requires a more complex setup, especially when working with maps. It’s ideal for resources that need individual configurations.

Approach 3: Dynamic Blocks

Dynamic blocks are useful for creating multiple blocks of a similar type within a resource or data source. It’s commonly applied in scenarios where a resource supports nested configurations.

  1. Identify the configuration that needs dynamic repetition within a resource.
  2. Use the dynamic block to iterate over a set or map, creating a nested configuration block for each item.

Example:

resource "aws_security_group" "example" {
  name        = "example-security-group"

  dynamic "ingress" {
    for_each = var.ingress_rules
    content {
      from_port   = ingress.value.from_port
      to_port     = ingress.value.to_port
      protocol    = ingress.value.protocol
      cidr_blocks = ingress.value.cidr_blocks
    }
  }
}

Notes: Dynamic blocks provide flexibility for configurations that require multiple, similar settings but maintain cleaner code. Beware of potential complexity and understand the structure of the resource being configured.

Conclusion

This overview of Terraform looping methods—count, for_each, and dynamic blocks—highlights the flexibility and power of Terraform for infrastructure as code. Each approach offers distinct advantages, whether you’re seeking simplicity with count, customization with for_each, or cleaner code with dynamic blocks. Selecting the right looping method depends on the specific requirements of your infrastructure project and the desired level of control over resource instantiation.