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.
_
何が悪いのですか?
ローカル値のfor
式association-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}"