State: 04.10.2021 – TF Version 1.0.8
It is not uncommon for resources to be required multiple times in terraform, sometimes even in unknown numbers. Often it can even happen that some resources are sometimes not needed at all and then again quite often. What possibilities does Terraform offer to create one or more resources in a flexible number?
A short overview:
- count
- for_each
- modularization in combination with the two above
Count
Probably the easiest method to use is the count meta argument, as Terraform calls it. On the one hand, it processes the length() or an int value to determine the number of passes. On the other hand, it can also be used for simple deploy/not-deploy statements with an if else statement.
After specifying the count within a resource, it will be deployed the same number of times. Within the resource the index can then be used with [count.index] on the used variables or already created resources.
Example (Multiple Resources with Count)
The shown resource group would now be deployed 2 times, once with the name rg-we-1 in the location West Europe and once with the name rg-we-2 in the location West Europe.
If the variable resource_group_names would be empty, Count = 0 and no deployment would take place.
variable "resource_group_names" = ["rg-we-1", "rg-we-2"] # Just for illustration
resource "azurerm_resource_group" "example" {
count = length(var.resource_group_names)
name = var.resource_group_names[count.index]
location = "West Europe"
}
Example (Count as a deploy/not deploy Statement)
The resource shown would now be deployed if var.deploy_resource_group = true. If this variable has the value „false“, no deployment would take place.
Instead of the blanket length „1“, this if-query could also be combined with the example above, thus substituting a flexible length for the true statement.
variable "deploy_resource_group" = true # Just for illustration
resource "azurerm_resource_group" "example" {
count = var.deploy_resource_group ? 1 : 0
name = "rg-we-1"
location = "West Europe"
}
For_each
Probably the best way to process large config objects or a list of config objects is a for_each loop. In contrast to the count, the length is not specified by a variable or a method, but by the number of objects to be processed within the specified variable.
When should you prefer a for_each to a count?
When several related variables have to be processed, which cannot be addressed by an integer.
Example (For_each with a config object and two related variables)
This example shows a simple config object with 2 variables. This object could be extended by infinitely more entries and would always be processed in the same way. Logically, these objects can also contain more variables and be significantly more complex. If this variable were empty, no deployment would take place.
variable "resource_group_config" = { # Just for illustration
{
name = "rg-we-1"
location = "West Europe"
},
{
name = "rg-ne-1"
location = "North Europe"
}
}
resource "azurerm_resource_group" "example" {
for_each = var.resource_group_config
name = each.value.name
location = each.value.location
}
Modularization
If there should be several resources in dependency and if they should be addressed by one and the same config object, my preferred choice would be the modularization of these resources.
What does this mean?
We would make use of the modularization of Terraform and swap the resources we want to address into a sub-module. This would mean that within this module, multiple resources can be created, using the same config object. In addition, we can control the module itself with a for_each or count and thus control the number of this combination of resources.
What should I use now?
In my opinion: Use for_each whenever possible and count only in extreme emergencies.
Why?
Resources which are created by count have the index of the resource in the terraform resource name and are always addressed to it. However, if from a list of 5 resources the 2nd resource is deleted or the config of this resource is removed, then the count of resources 3, 4 and 5 is changed to 2, 3 and 4. This has fatal consequences, because this addressing change within Terraforms would lead to the redeployment of the resource. This would be repeated every time should we change anything within this list. If any configs are attached to this list, we will not notice it. However, this can lead to unexpected consequences and should be avoided.
What does the addressing of the resources look like with for_each?
Each resource is addressed using the key, or the name of the resource. This makes the resource unique, but not dependent on a number or index value. Furthermore, it is much easier to query complex configurations if this does not have to be done using a fixed, very rigid index. This is simply not flexible enough.


Schreibe einen Kommentar