Last Updated on August 7, 2025 by Arnav Sharma
Using for_each in Terraform is a powerful way to deploy multiple resources based on a set of inputs. This method is particularly useful when you want to create multiple instances of a resource with only slight variations between them. Here’s how you can use for_each to deploy multiple resources:
Step 1: Define Your Input Set
First, you need to define a set of inputs that for_each will iterate over. This can be a list, set, or a map. Maps are often used because they allow you to easily associate each resource with a unique key.
For example, suppose you want to create multiple storage accounts in Azure. You might start with a map defining each account:
variable "storage_accounts" {
description = "A map of storage accounts to create"
type = map(object({
location = string
account_tier = string
account_replication_type = string
}))
default = {
"account1" = {
location = "eastus"
account_tier = "Standard"
account_replication_type = "LRS"
},
"account2" = {
location = "westus"
account_tier = "Standard"
account_replication_type = "GRS"
}
# Add more accounts as needed
}
}
Step 2: Use for_each in Your Resource Configuration
Next, use for_each in your resource block to iterate over each element in your input set. For each element, Terraform will create a new instance of the resource.
resource "azurerm_storage_account" "example" {
for_each = var.storage_accounts
name = each.key
location = each.value.location
account_tier = each.value.account_tier
account_replication_type = each.value.account_replication_type
# Other required fields...
}
In this example, each.key is the key from the storage_accounts map (e.g., “account1”, “account2”), and each.value is the corresponding value, which is an object with properties like location, account_tier, and account_replication_type.
Step 3: Initialize and Apply Your Terraform Configuration
- Run
terraform initto initialize the working directory. - Run
terraform planto see what resources Terraform will create or modify. - Run
terraform applyto create the resources.
Additional Tips
- Dynamic Blocks: For more complex scenarios, you might use
dynamicblocks within resources to create nested structures based on a list or map. - Dependency Management: Be mindful of dependencies between resources. Terraform automatically handles dependencies, but in some cases, you may need to explicitly define them.
- State Management: Each resource created with
for_eachwill have a unique identifier in the Terraform state file based on its key in the map. This helps in managing each resource independently. - Modifying the Set: If you modify the input set (e.g., add or remove an item), Terraform will add, update, or destroy resources to match the new set.
Using for_each can significantly simplify your Terraform configurations, especially when dealing with multiple similar resources. It ensures that your configurations are more dynamic and easier to maintain.
I help organisations secure their cloud infrastructure and stay ahead of evolving cyber threats. Microsoft MVP and Certified Trainer, author of Mastering Azure Security, and founder of arnav.au — a platform for practical Cloud, Cybersecurity, DevOps and AI content.
Frequently Asked Questions
for_each is used to iterate over maps or sets and creates resources with unique keys, making it ideal when you need to reference specific resource instances by their map keys. count, on the other hand, iterates over a list using numeric indices and is better for simpler scenarios. for_each is generally preferred for managing multiple similar resources because it provides more readable state management and easier resource tracking.
Yes, you can use for_each with a list, but Terraform requires converting it to a map first using the tomap() function or by using a for expression. Maps are preferred because they provide explicit keys for each resource, making your configuration more maintainable and reducing issues when items are added or removed from the collection.
You reference a specific resource created with for_each using the syntax: resource_type.resource_name[key]. For example, if you created storage accounts with for_each, you would reference the 'account1' resource as azurerm_storage_account.example["account1"]. This key-based reference makes it easy to access individual resources and their attributes.
When you remove an item from the for_each map and run terraform apply, Terraform will destroy the corresponding resource to match the new configuration. You'll see this destruction in the terraform plan output, so you can review the changes before applying them.
Yes, you can combine for_each with dynamic blocks for more complex scenarios where you need to create nested structures. This allows you to iterate over a map at the resource level with for_each while also using dynamic blocks within that resource to generate nested configurations based on lists or maps.