Choosing between for_each or count in Terraform
Find out when to use for_each vs. count in Terraform to avoid index drift, manage resources predictably, and write cleaner, scalable code.
Terraform's for_each and count meta-arguments are indispensable for creating multiple instances of resources or modules without redundant code. Both enable dynamic infrastructure, but understanding their distinct behaviors is crucial for effective and maintainable configurations.
What are count and for_each?
for_each: This meta-argument iterates over a map or a set of strings. For each item in the collection, Terraform creates a distinct instance of the resource or module, using the map key or set string as a unique identifier.
locals {
subnets = {
"subnet_a" = "10.0.1.0/24",
"subnet_b" = "10.0.2.0/24",
}
}
resource "aws_subnet" "main" {
for_each = local.subnets
vpc_id = aws_vpc.main.id
cidr_block = each.value # each.key is "subnet_a", "subnet_b"
# Example for AZ distribution, ensure data source is defined
# availability_zone = data.aws_availability_zones.available.names[index(keys(local.subnets), each.key)]
tags = {
Name = each.key
}
}
(Note: For the aws_subnet example, ensure aws_vpc.main and data.aws_availability_zones.available are properly defined in your configuration.)
count: This meta-argument takes a whole number and creates that many instances of a resource or module. Terraform tracks these instances using a numeric index (e.g., aws_instance.example[0], aws_instance.example[1]).
resource "aws_instance" "server_count" {
count = 3 # Creates 3 identical instances
ami = "ami-0c55b31ad20f0c502"
instance_type = "t2.micro"
tags = {
Name = "Server-${count.index + 1}"
}
}
Common Sticking Points
The primary confusion arises when deciding between them and understanding the implications:
- Refactoring and Instance Identity: If you use
countand remove an item from the middle of the list that generates the count, Terraform sees it as changing all subsequent resources. This can lead to unintended destruction and recreation.for_eachavoids this by using persistent string keys, making it more robust when managing collections where items might be added or removed. - Data Structures:
countis simpler for basic numerical repetition.for_eachrequires a map or a set of strings, sometimes necessitating data transformations with functions liketoset()orforexpressions to prepare the data. - Referencing Instances: Accessing specific instances differs:
resource_type.name[index]forcountvs.resource_type.name["key"]forfor_each.
The Scalr Perspective
While Terraform provides the mechanics, managing numerous dynamically created resources across different environments can become complex. A platform like Scalr aids by providing a structured environment where configurations, including those using for_each or count, are executed. Scalr's environment management can ensure that the inputs driving your iterations are consistent and auditable per environment. Furthermore, by using Scalr's policy enforcement (e.g., via OPA), you can set guidelines on how these iterators are used, perhaps flagging potentially risky count scenarios in critical environments, nudging teams towards the more stable for_each where appropriate. Visibility within the Scalr UI into all resources, regardless of how they were created, simplifies tracking.
Summary Table
Feature |
|
|
|---|---|---|
Input Type | Number | Map or Set of Strings |
Instance ID | Numeric Index (e.g., | String Key (e.g., |
Stability | Sensitive to order changes in lists | Robust to additions/removals if keys are stable |
Use Case | Identical resources, simple repetition | Unique resources from a collection, stable IDs |
Common Challenge | Unintended changes when list items shift | Data structure preparation, complex key management |
Conclusion
Both for_each and count are powerful. for_each is generally preferred for its stability when managing collections of unique resources. Understanding their differences is key to leveraging Terraform effectively. Platforms like Scalr can then provide the overarching structure and governance to manage these dynamic configurations safely at scale.