Terraform 0.12嵌套循环 [英] Terraform 0.12 nested for loops
问题描述
我正在尝试使用Terraform 0.12的新功能来实现嵌套循环,以便遍历AWS IAM用户,每个用户都可以附加一个或多个策略.用于表示此列表的变量的类型为map(list(string)),看起来像这样:
I am trying to implement nested for loops using Terraform 0.12's new features in order to loop through AWS IAM users, each of which can have one or more policies attached. The variable used to represent this list is of type map(list(string)) and looks something like this:
{
"user 1" = [ "policy1", "policy2" ],
"user 2" = [ "policy1" ]
}
通过keys()
可以很容易地获得要创建的用户列表,但是由于当前在Terraform中没有用于嵌套循环资源创建的机制,因此策略附件必须以独立于每个用户的单个循环的形式发生.因此,我正在尝试从地图输入中构建一个user:policy关联的列表,根据上面的示例,该列表看起来像这样:
Getting the list of users to create is easy enough via keys()
, but since there is currently no mechanism for nesting looped resource creation in Terraform, the policy attachments have to happen as a singular loop independent of each user. So, I am attempting to construct a list of user:policy associations from the map input that would look something like this based on the example above:
[
[ "user1", "policy1" ],
[ "user1", "policy2" ],
[ "user2", "policy1" ]
]
我正在尝试构造该列表并将其存储在本地变量中,如下所示,其中var.iam-user-policy-map
是输入映射:
I am attempting construct that list and store it in a local variable like so, where var.iam-user-policy-map
is the input map:
locals {
...
association-list = [
for user in keys(var.iam-user-policy-map):
[
for policy in var.iam-user-policy-map[user]:
[user, policy]
]
]
...
}
但是,尝试访问该嵌套列表中的值时出现错误.我正在尝试使用引用local.association-list[count.index][0]
和策略与local.association-list[count.index][1]
访问关联的用户部分,但是在运行terraform plan
时会出错:
However, I am getting errors when attempting to access the values in that nested list. I am trying to access the user portion of the association with the reference local.association-list[count.index][0]
and the policy with local.association-list[count.index][1]
, but on running terraform plan
it errors out:
Error: Incorrect attribute value type
on main.tf line 27, in resource "aws_iam_user_policy_attachment" "test-attach":
27: user = local.association-list[count.index][0]
Inappropriate value for attribute "user": string required.
Error: Incorrect attribute value type
on main.tf line 27, in resource "aws_iam_user_policy_attachment" "test-attach":
27: user = local.association-list[count.index][0]
Inappropriate value for attribute "user": string required.
Error: Invalid index
on main.tf line 28, in resource "aws_iam_user_policy_attachment" "test-attach":
28: policy_arn = "arn:aws-us-gov:iam::aws:policy/${local.association-list[count.index][1]}"
|----------------
| count.index is 0
| local.association-list is tuple with 2 elements
The given key does not identify an element in this collection value.
Error: Invalid template interpolation value
on main.tf line 28, in resource "aws_iam_user_policy_attachment" "test-attach":
28: policy_arn = "arn:aws-us-gov:iam::aws:policy/${local.association-list[count.index][1]}"
|----------------
| count.index is 1
| local.association-list is tuple with 2 elements
Cannot include the given value in a string template: string required.
我在做什么错了?
推荐答案
您的本地值association-list
中的for
表达式正在生成一个字符串列表列表,但是您对其的引用将其视为字符串列表的列表.
The for
expression in your local value association-list
is producing a list of list of lists of strings, but your references to it are treating it as a list of lists of strings.
要获得所需的展平表示,可以使用flatten
函数,但是因为否则它将把所有内容分组为单个平面列表,因此我建议将最里面的值设置为对象. (这还将使对它的引用更清晰.)
To get the flattened representation you wanted, you can use the flatten
function, but because it would otherwise group everything into a single flat list I'd recommend making the innermost value an object instead. (That will also make the references to it clearer.)
locals {
association-list = flatten([
for user in keys(var.iam-user-policy-map) : [
for policy in var.iam-user-policy-map[user] : {
user = user
policy = policy
}
]
])
}
该表达式的结果将具有以下形状:
The result of this expression will have the following shape:
[
{ user = "user1", policy = "policy1" },
{ user = "user1", policy = "policy2" },
{ user = "user2", policy = "policy2" },
]
您对它的引用可以采用以下格式:
Your references to it can then be in the following form:
user = local.association-list[count.index].user
policy_arn = "arn:aws-us-gov:iam::aws:policy/${local.association-list[count.index].policy}"
这篇关于Terraform 0.12嵌套循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!