Hey everyone 👋
If you're starting with Terraform or Infrastructure as Code (IaC), there's a good chance you'll run into the count
meta-argument pretty early. It’s one of those features that seems small — but saves you from writing 30 blocks of code for 30 identical servers.
Let me walk you through count
, how it works, why it matters, and the hidden gem that comes with it: count.index
👇
🎯 Imagine You’re Duplicating Infrastructure
Let’s say your DevOps team asks you to spin up 10 identical EC2 instances.
Before count
, you’d have to do this:
resource "aws_instance" "server1" { ... }
resource "aws_instance" "server2" { ... }
resource "aws_instance" "server3" { ... }
... all the way to server10
That’s 10 copy-pasted blocks. If something changes — say the AMI — you have to update all 10. Yikes 😩
🪄 Enter Terraform count
With count
, your code becomes:
resource "aws_instance" "server" {
count = 10
ami = "ami-123456"
instance_type = "t2.micro"
}
Done. 10 instances, same config, one block of code.
🧠 How count
Works (The Core Idea)
When you add count = 3
, Terraform:
✅ Creates 3 resources
✅ Names them with an index (like [0]
, [1]
, [2]
)
✅ Keeps your code clean and DRY (Don’t Repeat Yourself)
💡 Think of count
like a printing machine. Instead of writing each page by hand, you say “Print this template 10 times.”
🧩 But Wait… What If You Need to Customize Each One?
This is where count.index
comes in.
Let’s say you want each EC2 instance to have a unique name. You can’t just hardcode "Name = webserver"
— they’ll all be the same.
resource "aws_instance" "server" {
count = 3
ami = "ami-123456"
instance_type = "t2.micro"
tags = {
Name = "webserver-${count.index}"
}
}
✅ Result:
- webserver-0
- webserver-1
- webserver-2
💡 Think of count.index
like a jersey number for each player on a team — same outfit, different number.
🚨 The Gotcha: Unique Names in AWS
Some resources (like IAM users) require unique names. If you try this:
resource "aws_iam_user" "user" {
count = 3
name = "dev-user"
}
Only one user will be created. The rest will fail because usernames must be unique.
🧪 Solution? Add count.index
:
resource "aws_iam_user" "user" {
count = 3
name = "dev-user-${count.index}"
}
✅ Creates:
- dev-user-0
- dev-user-1
- dev-user-2
🧵 Even Better: Use Lists for Meaningful Names
What if you want real names instead of numbers? Use a list variable:
variable "users" {
type = list(string)
default = ["alice", "bob", "charlie"]
}
resource "aws_iam_user" "user" {
count = 3
name = var.users[count.index]
}
Result:
- alice
- bob
- charlie
💡 This is like having a guest list for a party — and handing out personalized invites 🎉
⚠️ One More Thing: count
Is Not Always Enough
While count
is great for identical resources, it’s not ideal when each resource needs totally different config.
That’s when you’ll reach for for_each
instead — but we’ll save that magic for another blog ✨
🧼 Final Thoughts
Terraform’s count
meta-argument (and its sidekick count.index
) gives you a powerful way to:
- Scale identical infrastructure with one line
- Customize each resource’s name or settings
- Avoid repetitive, error-prone code
Whether you’re spinning up servers or creating IAM users, count
helps you work smarter, not harder.
Let me know if you’ve used count
in creative ways — or if you’ve ever hit a weird bug with it, shameless plug ---> LinkedIn. Would love to hear your Terraform war stories 💬
Happy coding, cloud folks! ☁️👷♂️
Top comments (0)