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.