Chapter 9: Terraform Loop Battle: count vs for_each
In Terraform, it is inevitable that you will need to create multiple instances of the same resource or module. Terraform provides two meta-argumets to create loops under resource and module blocks:
count:it is used to create multiple copies of a resource in Terraform. It takes an integer value that specifies the number of copies to createfor_each:it is used to iterate over a map in Terraform
Let's create three resource groups using countand for_each loop as follows:
# Define a list of resource groups to create
variable "resource_groups" {
type = list(string)
default = ["rg-example-001", "rg-example-002", "rg-example-003"]
}
# Create resource groups with count
resource "azurerm_resource_group" "count_example" {
count = length(var.resource_groups)
name = "${var.resource_groups[count.index]}-count"
location = "North Europe"
}
# Create resource groups with for_each
resource "azurerm_resource_group" "for_each_example" {
for_each = toset(var.resource_groups)
name = "${each.key}-for_each"
location = "North Europe"
}
# Print all resource group names
output "resource_group_names" {
value = concat(
["${azurerm_resource_group.count_example.*.name}"],
["${values(azurerm_resource_group.for_each_example)[*].name}"]
)
}If you run the code, you will see:
If you carefully examine the output, you will notice that the resource group created in the count loop is created as a list: azurerm_resource_group.count_example[0], azurerm_resource_group.count_example[1], and azurerm_resource_group.count_example[2]. On the other hand, the resource groups created in the for_each loop are created as a map: azurerm_resource_group.for_each_example["rg-example-001"], azurerm_resource_group.for_each_example["rg-example-002"], and azurerm_resource_group.for_each_example["rg-example-003"].
This difference is significant because using count can make it more challenging to manage resources if you later need to adjust the number of resources. For instance, adding or removing a resource can affect other resources since the ordering of the list passed to the count loop will be modified.
The for_each expression allows you to create a variable number of resources based on the contents of a map. This can be useful if you need to create a dynamic number of resources or if you want to use a map to store resource configurations. To illustrate this, try removing "rg-example-002" from the default values and running the code again:
As you can see, Terraform compares the state file and notices that the resource_groups variable now only has two elements. The second element is not the resource it was expecting, so it destroys the existing resource group and creates a new one with the same name, just to store it in the state file as the second element. On the other hand, the for_each loop notices that a map element has been removed and simply tries to remove the corresponding element.
Last updated