Terraform
count reference
By default, each resource block and ephemeral block configures one real infrastructure object. Similarly, a module block includes a child module's contents into the configuration one time.
Use the count meta-argument to manage several similar objects, such as a fixed pool of compute instances, without writing a separate block for each object. When a resource or module block includes a count argument whose value is a whole number, Terraform creates that many instances.
Usage
The count meta-argument accepts a whole number and creates that many instances of the resource or module. Each instance has a distinct infrastructure object associated with it, and each is separately created, updated, or destroyed when the configuration is applied.
In the folllowing example, Terraform creates four aws_instance.server resources that use the same AMI and instance type. The count.index attribute gives each aws_instance a unique Name tag:
resource "aws_instance" "server" {
count = 4 # create four similar EC2 instances
ami = "ami-a1b2c3d4"
instance_type = "t2.micro"
tags = {
Name = "Server ${count.index}"
}
}
Expressions in count
The count meta-argument accepts numeric expressions, but unlike most arguments, the count value must be known before Terraform performs any remote resource operations. count cannot refer to any resource attributes that are only known after a configuration is applied, such as a unique ID generated by the remote API when an object is created.
Referring to instances
In blocks where count is set, Terraform creates an additional count object that you can use in expressions to modify the configuration of each instance. This object has the following attribute:
count.index: The distinct index number starting with0corresponding to this instance.
Terraform makes a distinction between the block containing the count argument and the instances associated with it. Terraform identifies instances index number starting at 0.
<TYPE>.<NAME>ormodule.<NAME>, for example,aws_instance.serverrefers to the resource block.<TYPE>.<NAME>[<INDEX>]ormodule.<NAME>[<INDEX>], for example,aws_instance.server[0]andaws_instance.server[1]refer to individual instances.
This is different from resources and modules without count or for_each, which can be referenced without an index or key.
Similarly, resources from child modules with multiple instances are prefixed
with module.<NAME>[<KEY>] when displayed in plan output and elsewhere in the UI.
For a module without count or for_each, the address will not contain
the module index as the module's name suffices to reference the module.
Within nested provisioner or connection blocks, the special self object refers to the current resource instance, not the resource block as a whole.
How to choose between count and for_each
count and for_each perform a similar function. Use the count argument when you want to create nearly identical instances. Use for_each when some instance arguments must have distinct values that can't be directly derived from an
integer index. You cannot use both a count and for_each argument in the same resource or module block.
Supported constucts
You can use count in the following Terraform configuration blocks:
Example use cases
The following use cases describe common patterns for the count argument.
Create multiple instances of module resources
In the following example, Terraform creates three EC2 instances, each with a unique name from the instance_names list:
locals {
instance_names = ["web", "api", "batch"]
}
module "ec2_instance" {
source = "terraform-aws-modules/ec2-instance/aws"
version = "6.0.2"
count = length(local.instance_names)
name = local.instance_names[count.index]
ami = data.aws_ami.latest_amazon_linux.id
instance_type = "t2.micro"
depends_on = [aws_s3_bucket.example]
}
Create multiple instances of a resource
The following example creates one instance for each subnet provided in the input variable:
variable "subnet_ids" {
type = list(string)
}
resource "aws_instance" "server" {
count = length(var.subnet_ids)
ami = "ami-a1b2c3d4"
instance_type = "t2.micro"
subnet_id = var.subnet_ids[count.index]
tags = {
Name = "Server ${count.index}"
}
}