github.com/hugorut/terraform@v1.1.3/website/docs/language/meta-arguments/count.mdx (about) 1 --- 2 page_title: The count Meta-Argument - Configuration Language 3 description: >- 4 Count helps you efficiently manage nearly identical infrastructure resources 5 without writing a separate block for each one. 6 --- 7 8 # The `count` Meta-Argument 9 10 -> **Version note:** Module support for `count` was added in Terraform 0.13, and 11 previous versions can only use it with resources. 12 13 -> **Note:** A given resource or module block cannot use both `count` and `for_each`. 14 15 > **Hands-on:** Try the [Manage Similar Resources With Count](https://learn.hashicorp.com/tutorials/terraform/count?in=terraform/0-13&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial on HashiCorp Learn. 16 17 By default, a [resource block](/language/resources/syntax) configures one real 18 infrastructure object. (Similarly, a 19 [module block](/language/modules/syntax) includes a 20 child module's contents into the configuration one time.) 21 However, sometimes you want to manage several similar objects (like a fixed 22 pool of compute instances) without writing a separate block for each one. 23 Terraform has two ways to do this: 24 `count` and [`for_each`](/language/meta-arguments/for_each). 25 26 If a resource or module block includes a `count` argument whose value is a whole number, 27 Terraform will create that many instances. 28 29 ## Basic Syntax 30 31 `count` is a meta-argument defined by the Terraform language. It can be used 32 with modules and with every resource type. 33 34 The `count` meta-argument accepts a whole number, and creates that many 35 instances of the resource or module. Each instance has a distinct infrastructure object 36 associated with it, and each is separately created, 37 updated, or destroyed when the configuration is applied. 38 39 ```hcl 40 resource "aws_instance" "server" { 41 count = 4 # create four similar EC2 instances 42 43 ami = "ami-a1b2c3d4" 44 instance_type = "t2.micro" 45 46 tags = { 47 Name = "Server ${count.index}" 48 } 49 } 50 ``` 51 52 ## The `count` Object 53 54 In blocks where `count` is set, an additional `count` object is 55 available in expressions, so you can modify the configuration of each instance. 56 This object has one attribute: 57 58 - `count.index` — The distinct index number (starting with `0`) corresponding 59 to this instance. 60 61 ## Using Expressions in `count` 62 63 The `count` meta-argument accepts numeric [expressions](/language/expressions). 64 However, unlike most arguments, the `count` value must be known 65 _before_ Terraform performs any remote resource actions. This means `count` 66 can't refer to any resource attributes that aren't known until after a 67 configuration is applied (such as a unique ID generated by the remote API when 68 an object is created). 69 70 ## Referring to Instances 71 72 When `count` is set, Terraform distinguishes between the block itself 73 and the multiple _resource or module instances_ associated with it. Instances are 74 identified by an index number, starting with `0`. 75 76 - `<TYPE>.<NAME>` or `module.<NAME>` (for example, `aws_instance.server`) refers to the resource block. 77 - `<TYPE>.<NAME>[<INDEX>]` or `module.<NAME>[<INDEX>]` (for example, `aws_instance.server[0]`, 78 `aws_instance.server[1]`, etc.) refers to individual instances. 79 80 This is different from resources and modules without `count` or `for_each`, which can be 81 referenced without an index or key. 82 83 Similarly, resources from child modules with multiple instances are prefixed 84 with `module.<NAME>[<KEY>]` when displayed in plan output and elsewhere in the UI. 85 For a module without `count` or `for_each`, the address will not contain 86 the module index as the module's name suffices to reference the module. 87 88 -> **Note:** Within nested `provisioner` or `connection` blocks, the special 89 `self` object refers to the current _resource instance,_ not the resource block 90 as a whole. 91 92 ## When to Use `for_each` Instead of `count` 93 94 If your instances are almost identical, `count` is appropriate. If some 95 of their arguments need distinct values that can't be directly derived from an 96 integer, it's safer to use `for_each`. 97 98 Before `for_each` was available, it was common to derive `count` from the 99 length of a list and use `count.index` to look up the original list value: 100 101 ```hcl 102 variable "subnet_ids" { 103 type = list(string) 104 } 105 106 resource "aws_instance" "server" { 107 # Create one instance for each subnet 108 count = length(var.subnet_ids) 109 110 ami = "ami-a1b2c3d4" 111 instance_type = "t2.micro" 112 subnet_id = var.subnet_ids[count.index] 113 114 tags = { 115 Name = "Server ${count.index}" 116 } 117 } 118 ``` 119 120 This was fragile, because the resource instances were still identified by their 121 _index_ instead of the string values in the list. If an element was removed from 122 the middle of the list, every instance _after_ that element would see its 123 `subnet_id` value change, resulting in more remote object changes than intended. 124 Using `for_each` gives the same flexibility without the extra churn.