Understanding Terraform Meta-Arguments: Count and For_Each


Introduction
When working with Infrastructure as Code (IaC) using Terraform, you often need to create multiple instances of the same resource. Instead of copying and pasting the same resource block multiple times, Terraform provides powerful meta-arguments like count
and for_each
that help you manage multiple similar resources efficiently. In this blog post, we'll dive deep into these meta-arguments and explore their practical applications.
What are Meta-Arguments?
Meta-arguments are special arguments in Terraform that can be used within any resource block to control how Terraform manages that resource. They're called "meta" arguments because they affect Terraform's behavior rather than configuring the resource itself.
The Count Meta-Argument
Understanding Count
The count
meta-argument is the simplest way to create multiple instances of a resource. It accepts a whole number and creates that many instances of the resource.
Example of Count
resource "aws_instance" "server" {
count = 3
ami = "ami-08c40ec9ead489470"
instance_type = "t2.micro"
tags = {
Name = "Server-${count.index + 1}"
Type = "Count Example"
}
}
In this example:
count = 3
creates three identical EC2 instancescount.index
is used to give each instance a unique name (Server-1, Server-2, Server-3)All other attributes remain identical across instances
When to Use Count
Creating multiple identical resources
Simple scaling scenarios
When you need numeric indexing
When the number of resources is determined by a variable
The For_Each Meta-Argument
Understanding For_Each
The for_each
meta-argument is more sophisticated than count
. It can iterate over either:
A map of key-value pairs
A set of strings
Example 1: For_Each with Set
locals {
instance_types = toset([
"t2.micro",
"t2.small",
"t3.micro"
])
}
resource "aws_instance" "server" {
for_each = local.instance_types
ami = "ami-08c40ec9ead489470"
instance_type = each.key
tags = {
Name = "Server-${each.key}"
Type = "ForEach Set Example"
}
}
Example 2: For_Each with Map
locals {
server_configs = {
"web" = {
instance_type = "t2.micro"
environment = "prod"
}
"app" = {
instance_type = "t2.small"
environment = "staging"
}
"db" = {
instance_type = "t3.micro"
environment = "dev"
}
}
}
resource "aws_instance" "server" {
for_each = local.server_configs
ami = "ami-08c40ec9ead489470"
instance_type = each.value.instance_type
tags = {
Name = "Server-${each.key}"
Environment = each.value.environment
}
}
When to Use For_Each
When resources need different configurations
When working with key-value pairs
When you need string-based keys instead of numeric indices
When you want more stable resource addressing
Count vs For_Each: Making the Right Choice
Advantages of Count
Simpler syntax
Good for numeric iterations
Works well with simple, identical resources
Easy to scale with variables
Advantages of For_Each
More flexible configuration options
Better for managing distinct resources
More stable when adding/removing resources
Clearer resource addressing
Practical Guidelines
Use
count
when:All instances are identical except for their index
You need simple numeric iteration
The number of resources might change frequently
Use
for_each
when:Resources need distinct configurations
You need named instances instead of numbered ones
You're working with maps of configuration data
You need more stable resource addressing
Real-World Implementation
Let's look at the output of our implementation:
Initialization: Run
terraform init
to set up the providerPlanning:
terraform plan
shows what will be createdApplication:
terraform apply
creates the resourcesVerification: Check AWS Console to see:
Count-based instances (Server-1, Server-2, Server-3)
ForEach set instances (different instance types)
ForEach map instances (web, app, db servers)
Best Practices
Use meaningful names in tags and identifiers
Keep resource configurations DRY (Don't Repeat Yourself)
Use locals for complex data structures
Document your code with clear comments
Always use version constraints for providers
Test with
terraform plan
before applying changes
Conclusion
Meta-arguments in Terraform are powerful tools for managing multiple resources efficiently. While count
offers simplicity for identical resources, for_each
provides flexibility for more complex scenarios. Understanding when to use each one will help you write more maintainable and scalable infrastructure code.
Remember to always clean up your resources with terraform destroy
when you're done experimenting to avoid unnecessary charges!
Subscribe to my newsletter
Read articles from Kanav Gathe directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
