When working with Terraform, you often need to create resources based on certain conditions—sometimes one, sometimes multiple, and occasionally none. Terraform offers two useful functions, count
and for_each
, to control how many resources are created. These can be used in different ways depending on what you want to achieve.
1. Using count
– Simple Conditional Resource Creation

count
allows you to control how many instances of a resource Terraform should create. Setting count
to 0
means the resource won’t be created. This approach is handy when you want to create or skip a resource based on a simple condition.
Example: Creating S3 buckets with count
Let’s say you want to create an S3 bucket only if the variable var.create_s3
is set to true
. If the value is false
, the bucket should not be created:
variable "create_s3" {
type = bool
default = true
}
resource "aws_s3_bucket" "example" {
count = var.create_s3 ? 1 : 0
bucket = "my-example-bucket"
acl = "private"
}
In this example, when var.create_s3
is true
, Terraform will create one S3 bucket. If var.create_s3
is false
, Terraform will skip creating the bucket.
2. Using for_each
– Creating Multiple Resources

If you need to create multiple resources based on a list or map of data, for_each
is a great tool. It lets you create a resource for every item in the collection, giving you more flexibility to control the number of resources dynamically.
Example: Creating multiple S3 buckets with for_each
Suppose you want to create multiple S3 buckets, with the number of buckets based on a list of names defined in a variable. You can use for_each
to create a bucket for each name in the list:
variable "bucket_names" {
type = list(string)
default = ["bucket1", "bucket2"]
}
resource "aws_s3_bucket" "example" {
for_each = toset(var.bucket_names)
bucket = each.value
acl = "private"
}
Here, Terraform will create one S3 bucket for each name in the var.bucket_names
list. If there are two names in the list, Terraform will create two buckets.
3. Sometimes Creating Multiple Resources, Sometimes None

There are situations where you may want to dynamically control how many resources get created—sometimes a few, and sometimes none at all. In these cases, combining for_each
with a logical condition can help. By passing an empty map to for_each
, you can ensure no resources are created when certain conditions aren’t met.
Example1: Conditionally creating multiple S3 buckets
Suppose you want to create several S3 buckets only if var.create_s3
is true
. If the condition is false, no buckets should be created. Here’s how you could implement this:
variable "create_s3" {
type = bool
default = true
}
variable "bucket_names" {
type = list(string)
default = ["bucket1", "bucket2"]
}
resource "aws_s3_bucket" "example" {
for_each = var.create_s3 ? toset(var.bucket_names) : {}
bucket = each.value
acl = "private"
}
If var.create_s3
is true
, Terraform will create buckets based on the list var.bucket_names
. If var.create_s3
is false
, the for_each
will be passed an empty map {}
, meaning no buckets will be created.
Example2: Conditionally creating multiple S3 buckets
variable "bucket_names" {
type = list(string)
default = ["bucket1", "bucket2"]
}
resource "aws_s3_bucket" "example" {
for_each = length(var.bucket_names) > 0 ? toset(var.bucket_names) : {}
bucket = each.value
acl = "private"
}
In this example for_each
checks if the bucket_names
list has any elements. If the list contains at least one element, S3 bucket resources will be created for each element in the list. If the list is empty, no resources will be created since for_each
receives an empty map ({}
).
This approach eliminates the need for an additional conditional variable and relies solely on the length of the bucket_names
list.
Standard Way
In addition to the techniques shown in this article, count
can also be used in the standard way to create multiple resources. For example, you may want to create several EC2s by simply adding a variable, or even just setting the count value:
hclCopy coderesource "aws_instance" "example" {
count = 3
ami = "ami-123456"
instance_type = "t2.micro"
}
This will create 3 instances of the resource.
The examples provided in this article demonstrate more advanced use cases where count
and for_each
can be applied conditionally or dynamically based on specific project needs. Terraform offers huge possibilities and a wide range of applications. It is worth reading the documentation carefully to fully use its potential in various projects. For more information, you can refer to the official Terraform documentation.
Summary
count
allows you to easily decide whether to create a resource based on a condition.for_each
lets you create multiple resources dynamically based on a list or map of data.- Combining
for_each
with logical conditions allows you to handle situations where you may need to create multiple resources or none at all.
Both approaches can be applied depending on the project’s needs and how dynamically we want to manage our cloud infrastructure. This is particularly useful when creating a module that is intended to be universal and flexible, adapting to various user requirements.