count meta-argument. count is useful for creating multiple copies of a resource from a single block, but it has important implications for identity, indexing, and lifecycle behavior. Read on for concise examples, common pitfalls, and guidance on when to prefer alternatives like for_each.
What count does
- Adding
count = Ntransforms a single resource block into a collection (a list) ofNinstances rather than a single instance. - Inside such a resource block you can reference
count.indexto get the current instance’s numeric index (starting at0). - Each instance’s identity is positional and based on its numeric index — Terraform tracks
resource.name[0],resource.name[1], etc., not by any human-readable name you assign.
azurerm_resource_group.rg[0]with namerg-0azurerm_resource_group.rg[1]with namerg-1
count.index exists only inside resource blocks that use count and increments from 0 to count - 1.
Use
count when instance identity is strictly positional (index-based) and you only need simple duplication with small index-driven differences (for example, suffixes or offsets). For long-lived infrastructure that requires stable identities, prefer for_each.count is a poor fit
- Identity is numeric and positional. If you change
count, Terraform will add or remove instances based on indices (it removes the highest indices first), not by any name or metadata you supply. - Non-index-based mappings between configuration and logical entities can result in surprising destroys and recreates when indexes shift.
- Minimal provider + counted resource groups
- Creating a related resource per index
count, use the same index so instances map 1:1:
sa[0] → rg[0], sa[1] → rg[1], and so on. Using matching indexes is a straightforward approach when instances should be paired by position.
- Binding all instances to a single (first) resource group
sa uses count, every sa[i] will be bound to rg[0]. If sa does not use count, this resource is simply created once in rg[0].
Reducing count and the destroy behavior
- Decreasing
countfrom3to2onazurerm_resource_group.rgcauses Terraform to plan to destroyrg[2](the highest index), because identities are positional. Example plan when decreasing:
- Removing a middle index (for example
rg[1]) is non-trivial. A targeted destroy like:
for_each is often better
countuses numeric, positional identity.for_eachuses stable keys (map keys or set elements) to give each instance a stable identity. Withfor_each, reordering, partial removals, or additions are less likely to cause unintended resource recreations.
Avoid using
count for resources where instance identity must remain stable across reorders, removals, or updates. Prefer for_each when you need deterministic, key-based identities for individual instances.countis a simple and effective way to duplicate resources when instance identity is purely positional.- Instances are identified by
index(0..N-1). Changes tocountadd or remove instances at the end of the list. - Removing a middle instance can lead to unintended destroys or recreations because identity is positional.
- For stable identities and safer updates, use
for_each.
- Official Terraform docs: https://www.terraform.io/docs
for_eachvscountguidance: https://www.terraform.io/docs/language/meta-arguments/count.html