For Expression
- Iterating: The for expression loops through each element of the value of the input complex type. Here, during that step, the current element is assigned to a variable (usually named
i
oritem
) for further processing.
- Transforming: The for expression then applies a transformation expression to the current element (i or item). The transformation expression can be any valid Terraform expression; you can extract, manipulate, or combine the properties of the current element in any way you need.
The syntax of a for expression is:
for i <complex-type> : <expression> if <condition>
Here is the breakdown of syntax:
for i in <complex-type>
: This part of the expression loops through each element in the input complex type and assigns the current element to the variable i (or any other variable name you choose).
<expression>
This part of the expression applies a transformation to the current element i. The result of this expression will be included in the final output.
if <condition>
(Optional) This part filters out certain elements from the input collection based on the specified condition.
variable "users" { default = [ { username = "ajay" age = 22 }, { username = "banar" age = 26 }, { username = "raja" age = 22 } ] } output "tranformed-var" { value = [for i in var.os : i.username] }
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
tranformed-var = [
"ajay",
"banar",
"raja",
]
In this example, var.users is an input list, and the transformation expression is i.username, which is used to extract a username from each user object. The result will be a new list that contains only usernames.
Input Types
1. Single temporary symbol:
In a For Expression, a single temporary symbol consists of single variable that represents the value of each element in the input collection. This type of symbol can be used with lists, sets, and tuples. When you use a single temporary symbol within a For Expression, Terraform assigns the value of each element in the input collection to that symbol. Then, you can use that symbol to change or manipulate the value in some way. Example
variable "list" { default = [1,2,3,4] } output "tranformed-var" { value = [for i in var.list : tostring(i)] }
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
tranformed-var = [
"1",
"2",
"3",
"4",
]
In the above example, the single temporary symbol, i represents the value of each element in the list input collection.
2. Pair of temporary symbols:
In a For Expression, a pair of temporary symbols consists of two variables that represent two different aspects of each element in the input collection. First symbol represents the
key
/index
of the element while the second symbol represents the value of the element. This type of symbol can be used on several input collections such as list, set, tuple, map, and object.
When the input collection is a list, set, or tuple, the first symbol i or idx represents the index of each element, starting from 0 and the second symbol v represents the value of each element.
variable "list" { default = [1,2,3,4] } output "tranformed-var" { value = {for i,v in var.list : i => tostring(v)} }
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
tranformed-var = [
"0" = "1",
"1" = "2",
"2" = "3",
"3" = "4",
]
When the input collection is a map or an object, then the first symbol k represents the key or attribute name of the current element and The second symbol v represents the value of each element in the collection.
variable "list" { default = { a = 1 b = 2 c = 3 d = 4 } } output "tranformed-var" { value = {for i,v in var.map : i => tostring(v)} }
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
tranformed-var = {
"a" = "1",
"b" = "2",
"c" = "3",
"d" = "4"
}
Result Types
The For Expression in Terraform has two possible result types: tuples (lists) and objects (maps). The type of brackets used defines the result type:
-
Square brackets [ ]
: When the For Expression uses square brackets [ ], the result is a tuple, or better said, a list. This means that the output will be a collection of values in which each value is associated with an index. Here is an example of a For Expression that produces a tuple result which, in this case, is actually a list:
variable "fruits" {
default = ["apple", "banana", "cherry"]
}
output "uppercase_fruits" {
value = [for fruit in var.fruits : upper(fruit)]
}
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
uppercase_fruits = [
"APPLE",
"BANANA",
"CHERRY",
]
In this example, the For Expression is using square brackets [ ] to return a tuple, or list, result. The result will be a list of fruit names in all uppercase, where each value has an index.
variable "fruits" {
default = ["apple", "banana", "cherry"]
}
output "uppercase_fruits" {
value = { for fruit in var.fruits : fruit => upper(fruit) }
}
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
uppercase_fruits = {
"apple" = "APPLE",
"banana" = "BANANA",
"cherry" = "CHERRY",
}
This example uses curly braces { } in the For Expression to produce an object (map) result. The result of this expression will be an object whose keys are names of fruit and values are their capital cases.
Filtering Elements in For Expressions
You can add an optional
if
clause to a for expression in order to filter out certain elements from the source collection. This will produce a result with fewer elements than the original collection.
variable "fruits" { type = list(string) default = ["apple", "banana", "", "orange", "", "grape"] } output "non_empty_fruits" { value = [for fruit in var.fruits : fruit if fruit != ""] }
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
uppercase_fruits = [
"apple",
"banana",
"orange",
"grape",
]
In this example the for expression is iterating over the fruits list and using an
if
clause to filter out the empty strings (""
). This is known as a 'filter'. The result of this will be a brand new list containing only the non-empty strings.
Element Ordering in For Expressions
When the for expressions are used to convert unordered data types like maps, objects and sets into ordered data types like lists and tuples, Terraform needs to make a decision on the order of elements.
Ordering Rules:
variable "fruits" {
default = {
d = 4
a = 1
c = 3
d = 2
}
}
output "uppercase_fruits" {
value = {for i,v in var.map : i => tostring(v)}
}
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
tranformed-var = {
"a" = "1",
"b" = "2",
"c" = "3",
"d" = "4"
}
In the above example, the keys of the output map are sorted alphabetically: "a", "b", "c", "d". The values retain their original order.
variable "fruits" {
type = set(string)
default = ["banar", "raja", "ajay"]
}
output "sorted-set" {
value = [for i in var.set : i]
}
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
sorted-set = [{
"ajay",
"banar",
"raja",
}]
Here, the elements of the output list are soreted in alphabetical order: "ajay", "banar", "raja".
Allowing Duplicate Keys in Map or Object
While creating an object in Terraform delimited by
{}
, all keys should be unique. If there is any duplication in keys, Terraform throws an error. Sometimes you will have a situation where many values have to share the same key. For example, think of the case where there is a list of users and their respective roles. If you try to create a map from this list using the role as the key, you get an error because of the duplicate keys.
variable "duplicate_keys" { default = { ajay = { role = "admin" }, banar = { role = "maintainer" }, raja = { role = "read-only" }, gavin = { role = "read-only" } } } output "keys" { value = {for username, value in var.duplicate_keys : value.role => username} }
Error: Duplicate object key
Two different items produced the key "read-only" in this 'for' expression. If duplicates are expected, use the ellipsis (...) │ after the value expression to enable grouping by key.
To handle this situation, Terraform provides a feature called
Grouping Mode
. Grouping Mode allows you to create a map where multiple values are associated with a single key. This is particularly useful when working with data that has duplicate keys. To activate Grouping Mode, you simply need to add ...
after the value expression in your for loop. This tells Terraform to create a map of lists, where each key can have multiple values.
variable "duplicate_keys" { default = { ajay = { role = "admin" }, banar = { role = "maintainer" }, raja = { role = "read-only" }, gavin = { role = "read-only" } } } output "keys" { value = {for username, value in var.duplicate_keys : value.role => username...} }
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
keys = {
"admin" = [
"ajay"
],
"maintainer" = [
"banar"
],
"read-only" = [
"raja",
"gavin"
]
}
Related Pages
- Variables - Input value and Output value
Feedback
Was this page helpful?