Terraform doesn’t have traditional for loops, but it uses for expressions to iterate over collections. The for expression allows iteration over lists or maps to generate new collections or values. It can be used in places like outputs, variables, and dynamic blocks.
How to use for_each to iterate over a list in Terraform
Key takeaways:
The
for_eachexpression enables the iteration over elements in a collection which allow you to manage similar resources dynamically and efficiently.The
for_eachexpression helps create multiple instances of a resource or module based on a list, map, or set of strings.Each element in the collection generates a distinct instance of the resource which makes it easy to handle multiple configurations.
The
for_eachexpression can be combined with variables to create resources based on dynamic or user-provided input.
In Terraform, efficient resource management is essential for handling infrastructure as code. As your infrastructure grows, manually defining each resource becomes impractical and error-prone. Here comes the for_each expression.
The for_each expression
In Terraform, the for_each expression allows you to iterate over a list or map and create multiple instances of a resource or module based on the elements of that list or map. This is useful when you want to manage multiple similar resources or configurations in a more dynamic way.
The for_each value must be a map or a set of strings, which creates an instance for each item in that map or set. Each instance has a distinct infrastructure object associated with it, and each is separately created, updated, or destroyed when the configuration is applied.
1. Using for_each on a list of strings
Here’s an example of using for_each to iterate over a list of strings and create resources dynamically.
provider "null" {}
variable "user_names" {
type = list(string)
default = ["user1", "user2", "user3"]
}
resource "null_resource" "users" {
for_each = toset(var.user_names)
triggers = {
name = each.value
}
}
output "user_names_output" {
value = [for user in null_resource.users : user.triggers.name]
}
Code explanation
Line 1: Defines the
nullprovider, which is a built-in provider that doesn’t perform any operations but can be useful for testing or generating data.Lines 3–6: Defines the
user_namesvariable, which is a list of strings. The default value is set to["user1", "user2", "user3"].Lines 8–14: Creates a
null_resourcenamedusers. Thefor_eachargument is set totoset(var.user_names), meaning the resource will be created for each unique string in theuser_nameslist. A trigger is set for each resource using the names from the list.Lines 16–18: Defines an output named
user_names_output, which uses a list comprehension to loop over eachnull_resource.usersinstance and extract thenamevalue from the triggers.
2. Using for_each on a list of objects
We can also use for_each to iterate over a list of complex objects. Here’s an example where for_each is used on a list of objects, each containing both a name and an age.
provider "null" {}
variable "users" {
type = list(object({
name = string
age = number
}))
default = [
{ name = "user1", age = 30 },
{ name = "user2", age = 25 },
{ name = "user3", age = 40 },
]
}
resource "null_resource" "users" {
for_each = { for u in var.users : u.name => u }
triggers = {
name = each.key
age = each.value.age
}
}
output "users_with_tags" {
value = { for user in null_resource.users : user.triggers.name => user.triggers.age }
}Code explanation
Lines 3–13: Defines a variable
users, which is a list of objects. Each object contains anameandagefield.Lines 15–22: Defines a
null_resourcenameduserswherefor_eachis used with aforexpression. This creates a map of user names as keys and the corresponding user objects as values. Inside thetriggersblock, each user’snameandageare set as triggers.Lines 24–26: Defines an output named
users_with_tags, which uses a map comprehension to loop over eachnull_resource.usersinstance and extract both thenameandagevalues from the triggers.
Conclusion
Using the for_each expression in Terraform is an effective way to dynamically manage multiple resources or configurations. By iterating over lists or maps, you can create and configure resources efficiently, ensuring that your Terraform configurations are scalable and flexible. Whether working with simple lists or more complex objects, the for_each function offers a robust solution to automate resource management.
Want to learn more? Dive deeper into “Beginner’s Guide to Terraform” and unlock your potential in infrastructure-as-code. Gain hands-on experience with managing remote resources, modules, and data structures to optimize your workflow.
Start mastering Terraform today!
Frequently asked questions
Haven’t found what you were looking for? Contact Us
Can you do a for loop in Terraform?
What is the difference between dynamic block and for_each in Terraform?
Can we use count and for_each in Terraform?
What is a disadvantage of using dynamic blocks in Terraform?
How to iterate over a list in Terraform
What is Infrastructure as Code?
Free Resources