Terraform - JSON の for ディレクティブ

Terraform - JSON の for ディレクティブ

IAM ポリシー リソース ブロック内の文字列値をループして、RDS IAM 認証を許可しようとしています。リソース定義は次のとおりです。

  resource "aws_iam_policy" "rds_iam_authentication"{
  name    = "${title(var.environment)}RdsIamAuthentication"
  policy  = templatefile(
    "${path.module}/iam_policy.json",
    {
      aws_account_id        = data.aws_caller_identity.current.account_id
      region         = var.region
      environment           = var.environment
      iam_rds_pg_role_name  = var.iam_rds_pg_role_name
    }
  )
}

iam_rds_pg_role_nameinの変数定義はterraform.tfvars次のとおりです。

region                  = "eu-west-3"
environment             = "env_name"
iam_rds_pg_role_name    = ["read_only_role", "full_role"]
aws_account_id          = "1234567890"

IAM ポリシー テンプレート ファイルは次のとおりです。

{
  "Version": "2012-10-17",
  "Statement": [
      {
          "Effect": "Allow",
          "Action": [
              "rds-db:connect"
          ],
          "Resource": [
            %{ for rds_role in iam_rds_pg_role_name ~}
              "arn:aws:rds-db:${region}:${aws_account_id}:dbuser:*/${rds_role}"
            %{ endfor ~}
          ]
      }
  ]
}

というエラーが表示されます

エラー: 「ポリシー」に無効な JSON が含まれています: 配列要素の後に無効な文字 '"' があります

この問題は json エンコーディングに関するものであると確信していますが、次のように json で arn 定義を実行しようとするとjsonencode、エラーは依然として発生します。

%{ for rds_role in iam_rds_pg_role_name ~}
    jsonencode("arn:aws:rds-db:${region}:${aws_account_id}:dbuser:*/${rds_role}")}
%{ endfor ~}

何が足りないのかを説明していただいたり、正しい方向を指し示していただいたりするとありがたいです。

前もって感謝します

答え1

IAM ポリシー テンプレート ファイルで、次の項目の末尾のコンマが欠落していますResource:

...
        "Resource": [
            %{ for rds_role in iam_rds_pg_role_name ~}
              "arn:aws:rds-db:${region}:${aws_account_id}:dbuser:*/${rds_role}",
                                                  there should be a comma here ^
            %{ endfor ~}
          ]
...

のインデックスと項目の両方をループしiam_rds_pg_role_name、インデックスが より小さい場合はコンマを追加できますlength(iam_rds_pg_role_name) - 1

...
        "Resource": [
            %{ for index, rds_role in iam_rds_pg_role_name ~}
              "arn:aws:rds-db:${region}:${aws_account_id}:dbuser:*/${rds_role}"%{ if idx < length(iam_rds_pg_role_name) - 1 },%{ endif }
            %{ endfor ~}
          ]
...

結果:

Terraform will perform the following actions:

  # aws_iam_policy.rds_iam_authentication will be created
  + resource "aws_iam_policy" "rds_iam_authentication" {
      + arn         = (known after apply)
      + id          = (known after apply)
      + name        = "Env_nameRdsIamAuthentication"
      + name_prefix = (known after apply)
      + path        = "/"
      + policy      = jsonencode(
            {
              + Statement = [
                  + {
                      + Action   = [
                          + "rds-db:connect",
                        ]
                      + Effect   = "Allow"
                      + Resource = [
                          + "arn:aws:rds-db:eu-west-3:1234567890:dbuser:*/read_only_role",
                          + "arn:aws:rds-db:eu-west-3:1234567890:dbuser:*/full_role",
                        ]
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + policy_id   = (known after apply)
      + tags_all    = (known after apply)
    }

関連情報