web-dev-qa-db-ja.com

Terraform 0.12 forループのネスト

AWS IAMユーザーをループするためにTerraform 0.12の新機能を使用してネストされたforループを実装しようとしています。それぞれに1つ以上のポリシーをアタッチできます。このリストを表すために使用される変数は、map(list(string))タイプで、次のようになります。

_{
  "user 1" = [ "policy1", "policy2" ],
  "user 2" = [ "policy1" ]
}
_

作成するユーザーのリストを取得するのはkeys()を使用すると十分簡単ですが、Terraformにはループリソースの作成をネストするメカニズムがないため、ポリシーのアタッチメントは各ユーザーに依存しない単一のループとして発生する必要があります。したがって、上の例に基づいて、次のようなマップ入力からuser:policyアソシエーションのリストを作成しようとしています。

_[
  [ "user1", "policy1" ],
  [ "user1", "policy2" ],
  [ "user2", "policy1" ]
]
_

私はそのリストを作成してローカル変数に格納しようとしています。ここで、_var.iam-user-policy-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_を実行するとエラーになります。

_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.
_

何が悪いのですか?

10
ViggyNash

ローカル値のforassociation-listは文字列のリストのリストのリストを生成していますが、それへの参照はそれを文字列のリストのリストとして扱っています。

必要なフラット化された表現を取得するには、flatten関数を使用できますが、そうしないとすべてがsingleフラットリストにグループ化されるため、代わりに最も内側の値をオブジェクトにすることをお勧めします。 (これにより、参照がより明確になります。)

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
      }
    ]
  ])
}

この式の結果は、次のような形になります。

[
  { user = "user1", policy = "policy1" },
  { user = "user1", policy = "policy2" },
  { user = "user2", policy = "policy2" },
]

参照は次の形式になります。

user = local.association-list[count.index].user
policy_arn = "arn:aws-us-gov:iam::aws:policy/${local.association-list[count.index].policy}"
11
Martin Atkins