Terraform Count Meta Argument: Examples & Pitfalls

Published: 2025-08-17
7 min read
Share:

The count meta argument allows Terraform to create multiple instances of a resource from a single configuration block.

Instead of duplicating the same resource definition repeatedly, you can specify how many instances Terraform should create. This reduces code duplication and makes infrastructure configurations easier to maintain.

If you're learning Terraform meta arguments, this feature is one of the first concepts you'll encounter when managing multiple servers, files, buckets, or other infrastructure resources.

Before continuing, it's helpful to understand the broader concept of Terraform Meta Arguments, since count is one of several mechanisms Terraform provides to control resource behavior.

What Is the Count Meta Argument in Terraform?

The count meta argument tells Terraform how many instances of a resource should be created.

When Terraform processes a resource that contains count, it converts that resource into a collection of indexed instances:

resource_type.resource_name[0]
resource_type.resource_name[1]
resource_type.resource_name[2]

Each instance receives a numeric index that starts at 0 and increases sequentially.

The official Terraform documentation lists count as one of the core meta arguments available for resources and modules.

Useful references:

How Count Meta Arguments in Terraform Work

Terraform evaluates the value assigned to count and creates that many resource instances.

Creating Multiple Resources

The following example creates three local files:

resource "local_file" "pet" {
  count    = 3
  filename = "/root/pet-${count.index}.txt"
  content  = "This is file ${count.index}"
}

Terraform creates:

  • /root/pet-0.txt
  • /root/pet-1.txt
  • /root/pet-2.txt

Each file is associated with a unique index.

Internally, Terraform tracks these resources as:

local_file.pet[0]
local_file.pet[1]
local_file.pet[2]

Understanding count.index

The count.index value represents the current resource instance being created.

For a resource with count = 3:

  • First instance → count.index = 0
  • Second instance → count.index = 1
  • Third instance → count.index = 2

This allows you to generate unique names, tags, paths, or configuration values for each resource.

Using Count with Lists and Variables

Hardcoding values works for simple examples, but real-world infrastructure often relies on variables.

Dynamic Resource Creation from Lists

You can calculate the number of resources dynamically by using the length of a list.

variable "filenames" {
  default = [
    "/root/pets.txt",
    "/root/dogs.txt",
    "/root/cats.txt"
  ]
}

resource "local_file" "pet" {
  count    = length(var.filenames)
  filename = var.filenames[count.index]
  content  = "Generated by Terraform"
}

Terraform automatically creates one resource for each item in the list.

If you add another filename, Terraform creates another resource. If you remove one, Terraform adjusts the resource count accordingly.

To learn more about variables, see:

Real-World Example: Creating Multiple EC2 Instances

One of the most common use cases for count is provisioning multiple identical virtual machines.

resource "aws_instance" "web" {
  count         = 3
  ami           = "ami-xxxxxxxx"
  instance_type = "t3.micro"

  tags = {
    Name = "web-${count.index}"
  }
}

Terraform creates:

  • web-0
  • web-1
  • web-2

This pattern is useful when deploying:

  • Development environments
  • Test servers
  • Worker nodes
  • Temporary infrastructure

If you're deploying AWS infrastructure with Terraform, these guides may help:

The Biggest Drawback of Count: Index Shifting

The biggest challenge with count appears when resource instances are created from lists.

Because Terraform tracks resources by numeric index, changing list order can cause unexpected replacements.

What Happens When You Remove an Item?

Consider the following list:

variable "filenames" {
  default = [
    "/root/pets.txt",
    "/root/dogs.txt",
    "/root/cats.txt"
  ]
}

Terraform creates:

local_file.pet[0] = /root/pets.txt
local_file.pet[1] = /root/dogs.txt
local_file.pet[2] = /root/cats.txt

Now remove the first item:

variable "filenames" {
  default = [
    "/root/dogs.txt",
    "/root/cats.txt"
  ]
}

Terraform sees:

local_file.pet[0] should now be /root/dogs.txt
local_file.pet[1] should now be /root/cats.txt

As a result, Terraform may:

  • Destroy the original resource at index 0
  • Replace resources whose indexes have shifted
  • Recreate resources that appear unchanged from a human perspective

I've seen teams accidentally trigger large replacement plans because a list item was removed from the middle of a configuration. Terraform wasn't wrong—the resource identities had genuinely changed from its perspective.

Why Terraform Replaces Resources

Terraform stores resources created with count using indexed addresses inside the state file:

aws_instance.web[0]
aws_instance.web[1]
aws_instance.web[2]

When indexes change, Terraform interprets those resources as different objects.

If you're new to Terraform state management, these articles provide useful background:

Visualizing Count Behavior with Outputs

You can inspect the generated resources by creating an output.

output "file_list" {
  value = local_file.pet[*].filename
}

After running:

terraform output

Terraform returns a list containing all generated filenames.

This is often the quickest way to verify how Terraform views a collection of resources created using count.

Count vs for_each: Which Should You Use?

Both count and for_each create multiple resources, but they solve slightly different problems.

Use count when:

  • Resources are nearly identical
  • You only need a numeric index
  • Resource identity is not important
  • You are creating a fixed number of resources

Use for_each when:

  • Resources have unique names
  • Resource identity must remain stable
  • Resources are based on maps or sets
  • List order may change frequently

Because for_each tracks resources using unique keys instead of indexes, it avoids most index-shifting issues.

For a deeper comparison, see the guide on the for_each meta argument in Terraform.

Best Practices for Using Count in Terraform

When working with count, follow these guidelines:

  • Use count for identical resources.
  • Avoid using count for resources with long-lived state.
  • Be cautious when removing or reordering list elements.
  • Review execution plans carefully before applying changes.
  • Prefer for_each when resource identity matters.
  • Keep resource naming predictable using count.index.

Pro Tip

If a resource stores important data or represents a production workload, think carefully before using count.

A resource replacement caused by index shifting can be harmless for temporary infrastructure but disruptive for stateful systems. In those situations, for_each is usually the safer choice.

Understanding count becomes easier when you also know these Terraform concepts:

Conclusion

The Terraform count meta argument is one of the simplest ways to eliminate repetitive infrastructure code.

It works well when you're creating multiple identical resources and only need numeric indexing to distinguish them.

Before using count in production, make sure you understand how Terraform tracks resource instances in state. Once you understand index shifting and its impact on resource replacement, you'll know when count is the right tool and when for_each is a better fit.

Frequently Asked Questions (FAQs)

What is the use of count in Terraform?

The count meta argument allows Terraform to create multiple instances of a resource from a single configuration block.

How does count.index work?

count.index represents the numeric index of the current resource instance. Indexing starts at 0.

Can I use count with variables?

Yes. A common pattern is using length() with a list variable to determine how many resources Terraform should create.

Why are resources recreated when I modify a list?

Terraform tracks resources created with count using numeric indexes. When indexes shift, Terraform may replace resources because their identities have changed.

When should I use for_each instead of count?

Use for_each when resources need stable identities or when you're working with maps and sets that use unique keys.

Can count be used with Terraform modules?

Yes. Terraform supports count on module blocks, allowing multiple instances of the same module to be created from a single configuration.

For details, refer to the official Terraform Count Documentation.

Free Engineering ToolsNEW

8 free, 100% client-side tools for developers — no signup, no data uploads.

Explore all tools