Hey Everyone! After a long time I am back with a new tutorial in Terraform series. If you’re just getting started with Terraform or you’ve been copying and pasting the same resource blocks over and over (we’ve all been there), this article is for you.
Terraform is your best friend when managing cloud resources, but writing everything by hand gets old fast. Think about that, you are needing 10 servers, 5 S3 buckets, or 20 security group rules… nobody wants to type all that out.
But here’s the best part, Terraform has built-in ways to loop and repeat things automatically. Once you learn these simple tricks, your configuration files will shrink dramatically, become easier to read, and stop driving you crazy when you need to change something.
We’ll cover three main looping tools everyone uses today:
- count (the classic one)
- for_each (the smarter, modern way)
- dynamic blocks (perfect for repeating stuff inside a resource)
Here is the practical examples, you need to start looping today. Let’s make your Terraform life a whole lot easier!
1. The famous count (still useful!)
If you’ve been writing Terraform code for a while, you probably started with something like this for creating multiple ec2 instances on AWS:
resource "aws_instance" "server1" { ami = "ami-123456" instance_type = "t3.micro" }
resource "aws_instance" "server2" { ami = "ami-123456" instance_type = "t3.micro" }
resource "aws_instance" "server3" { ami = "ami-123456" instance_type = "t3.micro" }
Copy-paste hell, right? Terraform has loops so you don’t have to do that anymore. using count you can easily launch number of ec2 instances with single code block as below.
resource "aws_instance" "web" {
count = 3
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "web-server-{count.index + 1}"
}
}
This creates 3 identical servers. count.index starts at 0, so we add +1 to make the names look nicer.
2. for_each – the better way most of the time
When you have a list or map of things (like different servers, users, buckets, etc.). You can use for_each that provides you more flexibility while creating resources with different-2 configurations.
variable "server_names" {
type = list(string)
default = ["frontend", "backend", "database"]
}
resource "aws_instance" "app" {
for_each = toset(var.server_names)
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = each.value
}
}
Or with a map if you want more details:
locals {
servers = {
"web1" = { type = "t3.micro", env = "prod" }
"web2" = { type = "t3.small", env = "prod" }
"dev1" = { type = "t3.micro", env = "dev" }
}
}
resource "aws_instance" "web" {
for_each = local.servers
ami = "ami-0c55b159cbfafe1f0"
instance_type = each.value.type
tags = {
Name = each.key
Env = each.value.env
}
}
3. Dynamic blocks (loops inside a resource)
The dynamic blocks are perfect for the things like IAM policy statements or ingress rules in security groups. Lets check an example:
hclresource "aws_security_group" "web" {
name = "web-sg"
dynamic "ingress" {
for_each = [80, 443, 22]
content {
from_port = ingress.value
to_port = ingress.value
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
This creates three separate ingress rules instead of writing them by hand.
Conclusion
This tutorial helped you to learn about using loops in Terraform. Here is a quick cheat sheet for you:
- Use
count, when you just want N copies of the same thing - Use
for_each, when every item is different or you care about stable names - Use
dynamicblocks, when you have repeating blocks inside a resource