Terraform 0.12 嵌套 for 循环 [英] Terraform 0.12 nested for loops

查看:29
本文介绍了Terraform 0.12 嵌套 for 循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Terraform 0.12 的新功能实现嵌套 for 循环,以便遍历 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 函数,但因为它会将所有内容分组到一个 single 扁平列表中,我建议您将最里面的值是一个对象.(这也将使对它的引用更加清晰.)

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 嵌套 for 循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆