Loops
for loop
- for Expressions in the docs
Syntax
[for ITEM in ITERABLE : EXPRESSION_USING_ITEM]
Iterate over a map of keys and values:
[for k, v in var.map : length(k) + length(v)]
Iterate of a list, using an optiona index.
[for i, v in var.list : "${i} is ${v}"]
Convert a list into a map:
{for s in var.list : s => upper(s)}
Sample result:
{
foo = "FOO"
bar = "BAR"
baz = "BAZ"
}
Examples
Get an attribute:
[for x in var.my_var : x.my_attribute]
Using a function:
[for x in var.my_var : chomp(x)]
Using a filter:
[for word in var.word_list : upper(word) if word != "coffee"]
Given an array:
[
{ name = "Foo"},
{ name = "Bar"}
]
You could get all the names as:
[for o in var.people : x.name]
Or the more succint splat:
var.people[*].name
Result:
["Arthur", "Martha"]
for_each
- for_each in the docs
Set for_each
as an attribute on a resource or module.
Array
For an array, you can use each.index
.
module "my_module" {
for_each = var.subpaths
message = "Problem reaching page: ${var.subpaths[each.index]}"
}
Map and set
If you have a map
or set
, then you can reference using each.key
and each.value
. You can use toset
to convert an array to a set - though this will mean order is not guaranteed and that any duplicates will be removed.
Here using each.key
and each.value
to get keys and values of a map.
my_map = {
foo = "bar",
fizz = "buzz"
}
resource "test_resource" "abc" {
for_each = var.my_map
my_key = each.key # e.g. "foo"
my_value = each.value # e.g. "bar"
}
Here, flattening some nested values. Based on article.
my_instances = {
instance_1 = {
ami = "ami-00124569584abc",
type = "t2.micro"
},
instance_2 = {
ami = "ami-987654321xyzab",
type = "t2.large"
},
}
resource "aws_instance" "test" {
for_each = var.my_instances
ami = each.value["ami"]
instance_type = each.value["type"]
}
For an array, you need to convert it to a set first with toset
.
This has duplication of the URL value. And that canโt be broken out as in variables or locals because for_each
references must be inside a module or resource.
module "my_module" {
for_each = toset(var.subpaths)
name = local.organic_name
message = "Problem reaching page: ${local.url_prefix}${var.main_url}/${each.key}"
url = "${local.url_prefix}${var.main_url}/${each.key}"
}
So, to avoid duplication:
module "my_module" {
for_each = toset([for subpath in var.subpaths : "${local.url_prefix}${var.main_url}/${subpath}"])
message = "Problem reaching page: ${each.value}"
url = each.value
}