github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/website/docs/language/meta-arguments/count.html.md (about)

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