Terraform(AWS)で次のような変数を用意し、key 「user1」のリストをループしたら、次にkey 「user2」のリストをループするといった処理を行いたい場合の方法についてメモ書きします。
今回の例では、ユーザーが対象のポリシーをリストに含む場合、そのポリシーをユーザーに付与するといったことを行なっています。
# variables.tf
variable "user_list" {
default = {
"user1" : [
"iam_policy_test",
"iam_policy_any1",
"iam_policy_any2",
],
"user2" : [
"iam_policy_any1",
"iam_policy_any2",
],
"user3" : [
"iam_policy_test",
],
}
}
ファイル構成
ファイル構成は以下のようになります。
.
├── config.tf
├── main.tf
└── variables.tf
config.tf は、required_providers などの基本的な設定を行なっているだけなので、今回は記載を省略します。
結論
下記のusers
で設定しているように、flatten([for k, l in var.user_list :[for v in l: <出力したい値>"]])
のように記載すれば意図した通りのループを行えます。
resource "aws_iam_policy_attachment" "this" {
name = "iam_policy_test"
users = flatten([for k, l in var.user_list :[for v in l: "${v == "iam_policy_test" ? k: ""}"]])
policy_arn = aws_iam_policy.this.arn
}
resource "aws_iam_policy" "this" {
name = "iam_policy_test"
policy = jsonencode({
"Version": "2012-10-17",
"Statement": [{}]
# 以下略
})
}
ループ処理の解説
この処理ではvariables.tfでiam_policy_test
を持つユーザーに対し、iam_policy_test
のポリシーを付与しています。
resource "aws_iam_policy_attachment"
のusers
はリストを渡す仕様となっています。
そのため、flatten関数で、for文で処理した内容をリスト(ネストされていない状態)にするようにしています。
for k, l in var.user_list:
の一週目では、k
にはuser1
、l
には["iam_policy_test","iam_policy_any1", "iam_policy_any2"]
のリストが入ります。
次の[for v in l: "${v == "iam_policy_test" ? k: ""}"]
で、l
の中身を順番にv
へ渡します。
その後v
をiam_policy_test
と比較し、同じ文字列だったらk
つまりuser1をusers変数の配列に入れるといった処理を繰り返します。
aws_iam_policyの設定について
resource "aws_iam_policy"
のpolicy
には、ユーザーに付与したい具体的なポリシーを設定します。
policy = jsonencode(<ポリシーのjson>)
の<ポリシーのjson>部分にAWSのビジュアルエディタで生成したjson、または既存ポリシーのjsonをそのままコピペすれば、terraformにも簡単にポリシーの設定を行えます。
実行結果
この処理をterraform plan すると次のようになります。
下から6行目付近でusers
にuser1とuser3が設定されていることを確認できます。
※ usersの""
となっているところは無視されます。
% terraform plan
Terraform used the selected providers to generate the following execution plan. Resource
actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_iam_policy.this will be created
+ resource "aws_iam_policy" "this" {
+ arn = (known after apply)
+ id = (known after apply)
+ name = "iam_policy_test"
+ path = "/"
+ policy = jsonencode(
{
+ Statement = [
+ {},
]
+ Version = "2012-10-17"
}
)
+ policy_id = (known after apply)
+ tags_all = (known after apply)
}
# aws_iam_policy_attachment.this will be created
+ resource "aws_iam_policy_attachment" "this" {
+ id = (known after apply)
+ name = "iam_policy_test"
+ policy_arn = (known after apply)
+ users = [
+ "",
+ "user1",
+ "user3",
]
}
Plan: 2 to add, 0 to change, 0 to destroy.