Reputation: 871
In have a list of dicts of which one key contains another list. I want to create an object that I can use in for_each
which would repeat key1, key2, list_key as many times as there are list items.
What would be the best way to iterate over it?
my_list = [
{
"key1" = "value1"
"key2" = "value2"
"list_key" = ["l_value1", "l_value2"]
},
{
"key1" = "value3"
"key2" = "value4"
"list_key" = ["l_value3"]
}
]
I tried flattening it in my locals using this method, but when I use it in for_each
it says for_each supports maps and sets of strings, but you have provided a set containing type object
.
locals {
params = flatten([
for element in var.my_list:
[
for k in element["list_key"]:
{
"key1" = element["key1"]
"key2" = element["key2"]
"list_key" = k
}
]
]
)
}
I'd then like to use it in my resource:
resource "an_aws_service" "my_service" {
for_each = toset(local.params)
name = each.value.key1
something = each.value.key2
something_else = each.value.list_key
}
If the output looked like this I could probably work with it with toset
, but maybe there are other ways to flatten it:
[{
"key1" = "value1"
"key2" = "value2"
"list_key" = "l_value1"
},
{
"key1" = "value1"
"key2" = "value2"
"list_key" = "l_value2"
},
{
"key1" = "value3"
"key2" = "value4"
"list_key" = "l_value3"
}]
Upvotes: 0
Views: 2325
Reputation: 16775
Your code with flattening
locals {
params = flatten([
for element in var.my_list :
[
for k in element["list_key"] :
{
"key1" = element["key1"]
"key2" = element["key2"]
"list_key" = k
}
]
]
)
}
...produces a list of objects (as the error message says, and also as you are pointing it out in your question):
name = [
{
"key1" = "value1"
"key2" = "value2"
"list_key" = "l_value1"
},
{
"key1" = "value1"
"key2" = "value2"
"list_key" = "l_value2"
},
{
"key1" = "value3"
"key2" = "value4"
"list_key" = "l_value3"
},
]
If you want to use this array to create multiple resources, you either transform this array into a map
:
resource "an_aws_service" "my_service" {
for_each = { for index, value in local.params : index => value }
name = each.value.key1
something = each.value.key2
something_else = each.value.list_key
}
Or use count
instead of for_each
:
resource "an_aws_service" "my_service" {
count = length(local.params)
name = local.params[count.index].key1
something = local.params[count.index].key2
something_else = local.params[count.index].list_key
}
You can not use a list of objects in a for_each
. You either have to have a map
(first example) or use count
instead of for_each
.
Upvotes: 2