for-each Meta Arguments in Terraform – Powerful Looping

for-each Meta Arguments in Terraform offer a cleaner, more predictable way to loop over complex resources. If you’ve been using the count meta argument but faced unexpected behavior during updates, switching to for_each might just be the solution you’re looking for.

In this post, we’ll explore what for_each does, how it differs from count, and how to use it properly for dynamic resource creation in Terraform.

Understanding the Need for for-each

The Problem with Count

Using count allows you to create multiple resources based on an integer value. However, it introduces limitations when you need to manage resources based on specific identifiers like filenames or server names.

When a list changes—for example, removing the first item—Terraform treats it as an index shift, destroying and recreating resources unnecessarily. This is not ideal in a production environment.

Enter for-each Meta Arguments

The for-each meta argument solves this problem by looping through maps or sets instead of lists. Rather than tracking resources by numerical index, for_each uses keys, which makes your infrastructure configuration more stable and readable.

Using for-each with Sets and Maps

Basic Syntax

Here’s a simplified structure:

resource "local_file" "pet" {
for_each = toset(var.filenames)
filename = each.value
content = "Generated by Terraform"
}

In this configuration:

  • for_each loops over a set.
  • each.value represents the current item in the loop.

This setup creates multiple files with unique names from the set.

Converting Lists to Sets for for-each

Why Lists Don’t Work Directly

Terraform does not allow for_each to loop over lists. If you try, it will throw a configuration error.

Solution 1: Define Variable as Set

You can directly define the variable like this:

variable "filenames" {
type = set(string)
default = ["/root/pets.txt", "/root/dogs.txt", "/root/cats.txt"]
}

This method works well when you’re sure there won’t be duplicates in your data.

Solution 2: Use the toset() Function

If you prefer using lists or your values are dynamic, convert them to a set using Terraform’s built-in toset() function:

for_each = toset(var.filenames)

This keeps your input flexible while making it compatible with for_each.

Why for-each is Better than Count

More Stable Resource Handling

When you delete an element using count, all following items shift their index. Terraform ends up recreating resources that haven’t actually changed.

With for_each, only the specific resource linked to the removed key is destroyed, while others remain untouched.

Example

Suppose your filenames set contains:

  • /root/pets.txt
  • /root/dogs.txt
  • /root/cats.txt

If you remove /root/pets.txt and reapply, only that one file is deleted. The rest stay exactly as they were.

Output Comparison: Count vs for-each

To see the difference, you can add an output block:

output "pet_files" {
value = local_file.pet
}

Output with Count

pet[0]
pet[1]
pet[2]

Output with for-each

pet["/root/dogs.txt"]
pet["/root/cats.txt"]

This distinction shows that with for_each, resources are managed as a map. Each item is associated with a unique key, making the structure more resilient to changes.

When to Use for-each in Terraform

Use for_each when:

  • You want to create resources with unique identifiers.
  • You need predictable and stable resource mapping.
  • You’re dealing with sets or maps.
  • You want to avoid the drawbacks of index-based updates.

Use count when:

  • You only need a specific number of identical resources.
  • Indexing is acceptable or useful.

Conclusion

for-each Meta Arguments in Terraform provide a smarter and more controlled way to loop through resources. By avoiding index-based resource management, you eliminate the risk of unnecessary resource replacement, especially when items are added or removed.

This method is not only more readable but also more maintainable and production-safe. Whether you’re building files, VMs, or cloud resources, for_each is an essential tool in every Terraform developer’s toolkit.

Frequently Asked Questions (FAQs)

1. What is the difference between count and for-each in Terraform?

count creates resources based on a numeric index, while for_each uses unique keys from a map or set, allowing more control.

2. Can I use for-each with a list?

No. Terraform does not allow for_each with lists directly. Convert the list to a set using the toset() function.

3. What types of collections work with for-each?

Terraform supports maps and sets with for_each. These ensure each resource is uniquely identified.

4. Why use for-each over count?

for_each avoids the issues of resource index shifting that occur with count, making updates safer and more predictable.

5. How do I prevent resource recreation using for-each?

Because for_each maps resources by key, only the specific key being changed is affected. Others remain untouched, minimizing disruption.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top