Hi Terraform Gurus!
I am using for_each
to import specific policies using import blocks
. However, I am facing difficulty in getting the ‘for_each’ function right for iterating over the policy. I need help correcting my ‘for_each’ function. My ultimate goal is to correctly import the policies. I would appreciate your assistance with this matter.
Here is my code
variable "users" {
type = list(object({
name = string
policies = list(string)
}))
default = [
{ name = "user1", policies = ["p1", "p2", "p99", "p200"] },
{ name = "user2", policies = ["p3", "p4"] },
{ name = "user3", policies = ["p5", "p6"] },
{ name = "user4", policies = ["p7", "p8"] },
]
}
import {
for_each = [for u in var.users : toset([for p in u.policies : p])]
to = aws_iam_policy.this[each.value.policies]
id = format("arn:aws:iam::054445454545:policy/%s", each.value.policies)
}
resource "aws_iam_policy" "this" {
for_each = [for u in var.users : toset([for p in u.policies : p])]
policy = each.value.policies
}
Hi @h2oearth,
Can you show exactly what the intended results should be? Your for_each
expression creates a list of sets, which doesn’t align with how you are using the value. The use of each.value.policies
implies you want an object with a policies
attribute, but that would not be valid as a string argument in format
.
Hi @jbardin ,
Thank you for your reply!
I have been experimenting with the for :-(. The goal is to be able iterate over the policies link to each user and use the individual policies on further steps.
The expected result from the format is arn:aws:iam::054445454545:policy/p1, arn:aws:iam::054445454545:policy/p2 ...
If I understand correctly, you are looking for the set of all policies, which could be written as:
toset(concat([for u in var.users : u.policies]...))
1 Like
I did not know that spread syntax was a possible :-O.
will this be the currect implementation? am I still able to retrive each policy by using each.value
?
variable "users" {
type = list(object({
name = string
policies = list(string)
}))
default = [
{ name = "user1", policies = ["p1", "p2", "p99", "p200"] },
{ name = "user2", policies = ["p3", "p4"] },
{ name = "user3", policies = ["p5", "p6"] },
{ name = "user4", policies = ["p7", "p8"] },
]
}
import {
for_each = toset(concat([for u in var.users : u.policies]...))
to = aws_iam_policy.this[each.value]
id = format("arn:aws:iam::054445454545:policy/%s", each.value)
}
Thank you, @jbardin, for your help! You made my day.
The spread syntax isn’t required, there’s a few ways to structure the same outcome, depending on what you find more readable
toset(flatten(var.users[*].policies))
If that configuration gives you the result you’re after, then it’s the correct implementation
1 Like