Using Count Meta-Argument
1. Creating Multiple Resources
| Property | Description | Values | Notes |
|---|---|---|---|
| count | Defines the number of instances to create | number |
Must be a positive integer or a reference to a variable |
Example: Creating Multiple S3 Buckets
resource "aws_s3_bucket" "bucket" {
count = 3
bucket = "my-bucket-${count.index}"
}
Note: The
count.index variable provides the index of each instance (0, 1, 2...).
Warning: Changing the
count value will cause Terraform to destroy and recreate resources, potentially leading to data loss.
Key Points
- count creates multiple instances of a resource
- Each instance has a unique
count.indexvalue - Changing
counttriggers resource recreation
2. Referencing Count Index
| Reference Type | Syntax | Description |
|---|---|---|
| count.index | count.index |
Index of the current instance in the count loop (0-based) |
| count.key | count.key |
Key of the current instance (only for for_each) |
Example: Using count.index in resource configuration
resource "aws_instance" "web" {
count = 3
ami = "ami-12345678"
instance_type = "t2.micro"
tags = {
Name = "web-${count.index}"
}
}
Note:
count.index is useful for creating unique resource names or assigning distinct values to each instance in a count loop.
3. Using Conditional Resource Creation (count = condition ? 1 : 0)
Use the count meta-argument with a conditional expression to conditionally create resources based on a boolean condition.
| Property | Description | Example |
|---|---|---|
| count | Number of instances to create. If 0, no resources are created. | count = var.create_instance ? 1 : 0 |
Example: Conditional EC2 Instance Creation
resource "aws_instance" "web" {
count = var.create_web_server ? 1 : 0
ami = "ami-12345678"
instance_type = "t2.micro"
}
Note: When
count = 0, the resource is completely skipped and not managed by Terraform.
Warning: Using
count = 0 does not prevent dependencies from being evaluated. If a resource depends on this conditional resource, it will still be processed.
4. Accessing Count Resources
| Resource Reference | Syntax | Description |
|---|---|---|
| resource.type.name | aws_instance.web[0] |
Access the first instance in a count loop |
| resource.type.name | aws_instance.web[1] |
Access the second instance in a count loop |
| resource.type.name | aws_instance.web[count.index] |
Access resource by index variable |
Example: Accessing Count Resources in Variables
variable "instance_ids" {
type = list(string)
default = [for instance in aws_instance.web : instance.id]
}
output "first_instance_id" {
value = aws_instance.web[0].id
}
Note: When using
count.index, ensure that the resource count is known at apply time to avoid runtime errors.
5. Understanding Count Limitations
| Limitation | Description | Impact |
|---|---|---|
| Index Availability | Count creates a list of resources, but individual resource indexes are not directly accessible in some contexts (e.g., within for_each loops or complex expressions). |
Requires careful use of count.index for referencing specific instances. |
| State Management | Changing the count value causes Terraform to destroy and recreate resources, which can lead to data loss if not handled carefully. |
State drift and potential downtime during updates. |
| Conditional Logic | Using count with conditional logic (e.g., count.index < 5) can make state management more complex and harder to predict. |
Increased risk of misconfiguration and unexpected behavior in state files. |
| Resource Dependencies | When using count, dependencies between resources must be explicitly defined to avoid unintended order of operations. |
Potential for race conditions or incorrect resource creation order. |
Note:
count is not suitable for all use cases. For more dynamic resource creation, consider using for_each or custom modules.Warning: Modifying the
count value in an existing configuration can cause resource recreation and data loss. Always back up your state before making such changes.6. Using Count with Modules
| Property | Description | Example |
|---|---|---|
| count | Number of instances to create for a module | count = 3 |
| count.index | Index of the current module instance (0-based) | count.index |
Example: Creating Multiple S3 Buckets
module "bucket" {
source = "./s3-bucket"
count = 3
name = "my-bucket-${count.index}"
}
Note: When using
count with modules, the module instances are created in order, and count.index can be used to differentiate each instance.
Warning: Changing the
count value can cause Terraform to destroy and recreate resources, leading to data loss. Always verify the plan before applying changes.
7. Handling Count Changes
| Change Type | Description | Impact | Action Required |
|---|---|---|---|
| count = 0 | Resource is destroyed | Resource instance removed from state | None, unless dependencies exist |
| count = 1 → count = 3 | Resource instances created | New instances added to state | Review new instances for configuration |
| count = 3 → count = 1 | Resource instances destroyed | Instances removed from state | Ensure data is backed up or migrated |
| count = 2 → count = 2 (same) | No change in count | State unchanged | None |
Example: Changing Count Value
resource "aws_instance" "web" {
count = 3
ami = "ami-12345678"
instance_type = "t2.micro"
}
Note: When count changes, Terraform will destroy and recreate resources in a way that preserves state for each instance.
Warning: Changing count from a non-zero value to zero will destroy all instances. Ensure backups or data migration are in place.
8. Combining Count with Conditionals
| Property | Description | Usage |
|---|---|---|
| count | Controls how many instances of a resource to create | count = 3 |
| count.index | Index of the current resource instance (0-based) | count.index |
| count.value | Value of the count variable (only available in loops) | count.value |
Example: Conditional Resource Creation with Count
resource "aws_instance" "web" {
count = var.create_web_servers ? 2 : 0
ami = "ami-12345678"
instance_type = "t2.micro"
tags = {
Name = "web-${count.index}"
}
}
Example: Using Count with Conditionals in Variables
variable "create_servers" {
description = "Whether to create servers or not"
type = bool
default = true
}
resource "aws_instance" "app" {
count = var.create_servers ? 3 : 0
ami = "ami-87654321"
instance_type = "t3.micro"
tags = {
Name = "app-${count.index}"
}
}
Note: When using
count with conditionals, ensure that the conditional logic evaluates to a number or boolean. If you're using a variable that might be null, use var.name != null to check for existence before applying the conditional.
Warning: Changing
count from a number to zero or vice versa will cause Terraform to destroy and recreate resources, which can lead to data loss. Always verify the impact before making such changes.
9. Using Count with Data Sources
| Property | Description | Example |
|---|---|---|
| count | Number of instances to create from a data source | count = 3 |
| for_each | Iterate over a map or set to create multiple data source instances | for_each = var.instances |
Example: Using count with data sources
data "aws_subnet" "subnet" {
count = 3
id = aws_subnet.subnet_ids[count.index]
}
output "subnet_ids" {
value = data.aws_subnet.subnet[*].id
}
Note: When using
count with data sources, the index is accessible via count.index.
Example: Using for_each with data sources
data "aws_instance" "instance" {
for_each = var.instances
instance_id = each.value.id
}
output "instance_ids" {
value = [for instance in data.aws_instance.instance : instance.id]
}
Warning: Changing
count or for_each values can cause data source re-creation, which may lead to data loss or unexpected behavior.
10. Converting Count to For-Each
| Aspect | Count | For-Each |
|---|---|---|
| Usage | count = 3 |
for_each = var.instances |
| Index Access | count.index |
for_each.key |
| Resource Reference | aws_instance.example[count.index] |
aws_instance.example[for_each.key] |
| Behavior on Change | Recreates resources if count changes | Updates resources if for_each map changes |
Example: Converting Count to For-Each
# Before (using count)
resource "aws_instance" "example" {
count = 3
ami = "ami-12345678"
instance_type = "t2.micro"
tags = {
Name = "instance-${count.index}"
}
}
# After (using for_each)
variable "instances" {
default = [ "web", "db", "app" ]
}
resource "aws_instance" "example" {
for_each = var.instances
ami = "ami-12345678"
instance_type = "t2.micro"
tags = {
Name = "instance-${for_each.key}"
}
}
Note:
for_each is preferred over count for managing multiple resources with different configurations.
Warning: Changing the
for_each map will cause all resources to be recreated if not handled carefully.