# Using some loop with count and for\_each. Availability zones and server count

**URL:** <https://discuss.hashicorp.com/t/using-some-loop-with-count-and-for-each-availability-zones-and-server-count/7779>\
**Category:** Terraform\
**Created:** [April 17, 2020, 4:05pm UTC](https://discuss.hashicorp.com/t/using-some-loop-with-count-and-for-each-availability-zones-and-server-count/7779 "2020-04-17T16:05:30Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![tluv2006](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/tluv2006/32/6091_2.png) [@tluv2006](https://discuss.hashicorp.com/u/tluv2006)\
**Post date:** [April 17, 2020, 4:05pm UTC](https://discuss.hashicorp.com/t/using-some-loop-with-count-and-for-each-availability-zones-and-server-count/7779/1 "2020-04-17T16:05:30Z")

</div>

Im trying to do a module for a module build. I have a count statement for the vm build but now I need to use a for each to rotate through a list.

locals {  
zone = toset([“1”,“2”,“3”])  
}  
resource “azurerm\_windows\_virtual\_machine” “main” {

# for\_each = locals.zones

# zone = each.value

count = var.itemCount

and the Module would look like this:

module “webservers” {

source = “./module”

itemcount = “3”

* * *

The problem is terraform does not allow count and for\_each in the same module / block. I need this because I’m doing a count for the server number and a for\_each to stick the vms in a availability zone.

Help please!!!

---

<div class="post-metadata">

**Author:** ![apparentlymart](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/apparentlymart/32/702_2.png) [@apparentlymart](https://discuss.hashicorp.com/u/apparentlymart)\
**Post date:** [April 17, 2020, 4:41pm UTC](https://discuss.hashicorp.com/t/using-some-loop-with-count-and-for-each-availability-zones-and-server-count/7779/2 "2020-04-17T16:41:46Z")

</div>

Hi @tluv2006,

When working with `for_each` our task is to construct a collection that has one element for each of the instances we want to create. In your case, it seems like you want three instances per each element in your collection. A different way to say that is that you want one instance for each unique combination of elements from `local.zone` and elements from the sequence `[0, 1, 2]`.

We can construct a sequence like `[0, 1, 2]` using [the `range` function](https://www.terraform.io/docs/configuration/functions/range.html):

```auto
> range(3)
[0, 1, 2]

```

To combine that with your set of zones we can use nested [`for` expressions](https://www.terraform.io/docs/configuration/expressions.html#for-expressions) along with [`flatten`](https://www.terraform.io/docs/configuration/functions/flatten.html) so that the result is just a flat list, rather than a list of lists:

```auto
locals {
  # (I renamed the zones to letters so that they'd
  # be more distinct from the instance indices.)
  zones = ["a", "b", "c"]
  instance_idxs = range(var.itemcount)

  instances = flatten([
    for z in local.zones : [
      for i in local.instance_idxs : {
        zone = z
        index = i
      }
    ]
  ])
}

```

The `local.instances` value will now look something like this:

```auto
[
  { zone = "a", index = 0 },
  { zone = "a", index = 1 },
  { zone = "a", index = 2 },
  { zone = "b", index = 0 },
  { zone = "b", index = 1 },
  { zone = "b", index = 2 },
  { zone = "c", index = 0 },
  { zone = "c", index = 1 },
  { zone = "c", index = 2 },
]

```

That list contains one element per instance of `azurerm_windows_virtual_machine` you want to create, so all that remains is to project that into a map in the `for_each` expression so that the map keys can be used to track each individual instance:

```auto
resource "azurerm_windows_virtual_machine" "main" {
  for_each = { for inst in local.instances : "${i.zone}_${i.index}" => i }

  name = "example_${each.key}"
  zone = each.value.zone
  # ...
}

```

The above tells Terraform to track these instances using addresses like this:

- `azurerm_windows_virtual_machine.main["a_0"]`
- `azurerm_windows_virtual_machine.main["a_1"]`
- `azurerm_windows_virtual_machine.main["a_2"]`
- `azurerm_windows_virtual_machine.main["b_0"]`
- `azurerm_windows_virtual_machine.main["b_1"]`
- …

This means that if you add a new item `d` to `local.zones`, Terraform will understand that as a request to create three new instances and leave the others undisturbed:

- `azurerm_windows_virtual_machine.main["d_0"]`
- `azurerm_windows_virtual_machine.main["d_1"]`
- `azurerm_windows_virtual_machine.main["d_2"]`

…and if you decrease `var.itemcount` to 2 then Terraform will understand that as a request to delete all of the ones with index 2, leaving indices 0 and 1 intact:

- `azurerm_windows_virtual_machine.main["a_2"]`
- `azurerm_windows_virtual_machine.main["b_2"]`
- `azurerm_windows_virtual_machine.main["c_2"]`
- `azurerm_windows_virtual_machine.main["d_2"]`

For this reason, it’s important to ensure that the keys in the `for_each` map capture your intended unique identifier for each instance: Terraform will use the keys to understand how to interpret a change to the input as a planned change to the remote objects you’re managing with Terraform.
