TFNFR7 - Count & for_each Use
We can use count
and for_each
to deploy multiple resources, but the improper use of count
can lead to
anti pattern
.
You can use count
to create some kind of resources under certain conditions, for example:
resource "azurerm_network_security_group" "this" {
count = local.create_new_security_group ? 1 : 0
name = coalesce(var.new_network_security_group_name, "${var.subnet_name}-nsg")
resource_group_name = var.resource_group_name
location = local.location
tags = var.new_network_security_group_tags
}
The module’s owners MUST use map(xxx)
or set(xxx)
as resource’s for_each
collection, the map’s key or set’s element MUST be static literals.
Good example:
resource "azurerm_subnet" "pair" {
for_each = var.subnet_map // `map(string)`, when user call this module, it could be: `{ "subnet0": "subnet0" }`, or `{ "subnet0": azurerm_subnet.subnet0.name }`
name = "${each.value}"-pair
resource_group_name = azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.1.0/24"]
}
Bad example:
resource "azurerm_subnet" "pair" {
for_each = var.subnet_name_set // `set(string)`, when user use `toset([azurerm_subnet.subnet0.name])`, it would cause an error.
name = "${each.value}"-pair
resource_group_name = azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.1.0/24"]
}