Demystifying For Loops in Terraform: A Practical Guide
Tags: terraform, devops, cicd, aws
Published: 2023-06-15 12:56:39

Terraform is a popular infrastructure as a code tool that allows you to define and manage cloud resources. 

One of the powerful features of Terraform is the ability to use `for` loops. 

The `for` loops in Terraform provide a powerful mechanism for iterating over a list of items and performing actions or creating resources dynamically. 

This capability allows for efficient and flexible infrastructure provisioning, reducing manual effort and enhancing scalability.

In this guide, I walk you through the syntax and benefits of for loops in Terraform, providing practical insights and examples to help you leverage their power effectively.

## Understanding For Loops in Terraform

To leverage for loops, you start by defining a variable that represents the list of items you want to iterate over, then, you use either the `for_each` or `count` expressions to control the iteration. 

The `count` expression is suitable for iterating a fixed number of times, while the `for_each` expression is particularly useful when you have a dynamic set of items, such as a map or set.

**But, what do I mean by the map and set?**

The `for_each` map is like [dictionaries](https://www.w3schools.com/python/python_dictionaries.asp) in Python, where variables have attributes with keys mapped to a value, while the set is similar to a [list](https://www.w3schools.com/python/python_lists.asp) - an ordered collection of objects.

Here's an example of a Terraform code snippet that demonstrates the use of `for_each` and `count` expressions in different use cases:

```
# Dynamic set of items using for_each
variable "dynamic_items" {
  type    = map(string)
  default = {
    ubuntu_server = "ami-01dd271720c1ba44f“ 
    windows_server = "ami-0274fd9e256dea7b1“ 
    rhel_server = "ami-013d87f7217614e10“ 
  }
}

resource "aws_instance" "servers" {
  for_each = var.dynamic_items

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

  tags = {
    Name = each.key
  }
}

```

In this example, the `for_each` expression is used to create AWS EC2 instances based on the dynamic set of items defined in the dynamic_items variable. Each item in the map represents a server name and its corresponding types - machine image (ami). The aws_instance resource will be created for each server in the map, and the instance tags will be set using the for_each iterator.

On the other hand, the `count` expression is used to create AWS EBS volumes iteratively based on the fixed count defined in the fixed_count variable. The `aws_ebs_volume` resource will be created three times, with each volume having a different name specified using the count.index variable (DataVolume-1, DataVolume-2, DataVolume-3).

```
# Fixed number of iterations using count
variable "fixed_count" {
  type    = number
  default = 3
}

resource "aws_ebs_volume" "data_volume" {
  count          = var.fixed_count
  availability_zone = "us-west-1a"
  size           = 100
  volume_type    = "gp2"

  tags = {
    Name = "DataVolume-${count.index + 1}"
  }
}
```

By using for loops, instead of manually defining multiple resource blocks or modules, you can dynamically generate resources, this eliminates the need for repetitive code and reduces the chances of errors.

They also enable easy scalability, this allows you to adapt to changing requirements and easily handle larger infrastructure deployments. Whether you need to create multiple EC2 instances, provision multiple subnets, or configure multiple security groups, for loops provide a convenient mechanism to scale your infrastructure.

In addition to automation, they also support conditional statements, you can incorporate if conditions and logical expressions within for loops to control the iteration process and make dynamic decisions based on specific criteria.

## Best Practices

When working with for loops in Terraform, maintaining code readability and organization is essential for ensuring long-term maintainability and collaboration. Here are some best practices to consider:

- Use meaningful variable names: Choose descriptive names for your variables to enhance code readability. This makes it easier for others (and yourself) to understand the purpose and context of the loop.

- Add comments: Include comments within your code to provide explanations and document the intention behind the for loop. This helps others grasp the logic and purpose of the iteration.

- Indentation and formatting: Consistently apply proper indentation and formatting to your for loops. 

- Limit loop complexity: Avoid overly complex for loops with nested iterations or extensive conditional statements. Excessive complexity can make code difficult to understand and maintain.

- Test and validate: Before deploying for loops in production environments, thoroughly test and validate their functionality.

## The End -
Summarily, the power of for loops in Terraform empowers you to automate resource creation and configuration while providing flexibility through conditional statements. Moreover, the inclusion of conditional statements allows you to adapt to different scenarios, making your infrastructure setups more dynamic and adaptable to changing requirements.

For a more in-depth tutorial, take a look at this [article](https://www.cloudbolt.io/terraform-best-practices/terraform-for-loops/).