継続は力なり

タイトル通り定期的な更新を心掛けるブログです。

terraform-aws-provider 5.68.0 で非推奨になった aws_iam_role の inline_policy の改修を行ったときのメモ✍

タダです.

terraform-aws-provider 5.68.0 で以下の引用文にあるように aws_iam_role にて inline_policy を使用するのが非推奨になり aws_iam_role_policy が代替先になりました.この記事では,そのリソースの改修を行った備忘録を書きます.

resource/aws_iam_role: The inline_policy argument is deprecated. Use the aws_iam_role_policy resource instead.

github.com

inline_policy から aws_iam_role_policy へ書き換え

aws_iam_roleinline_policy を使用していた下記の IAM リソースがあったとします.この状況で terraform plan を試すと Warning: Argument is deprecated が表示されます.

data "aws_iam_policy_document" "ecs_task_assume" {
  statement {
    effect = "Allow"
    actions = [
      "sts:AssumeRole",
    ]
    principals {
      type = "Service"
      identifiers = [
        "ecs-tasks.amazonaws.com",
      ]
    }
  }
}
resource "aws_iam_role" "blog_role" {
  name               = "blog-role"
  assume_role_policy = data.aws_iam_policy_document.ecs_task_assume.json
  inline_policy {
    name = "blog-role-inline-policy"
    policy = jsonencode({
      Version = "2012-10-17"
      Statement = [
        {
          Action = [
            "s3:*",
          ]
          Effect   = "Allow"
          Resource = [
            "arn:aws:s3:::somebucket",
            "arn:aws:s3:::somebucket/*",
          ]
        },
      ]
    })
  }
}

terraform plan 実行結果

Warning: Argument is deprecated
 
   with aws_iam_role.blog_role,
   on blog_role.tf line 15, in resource "aws_iam_role" "blog_role":
   15: resource "aws_iam_role" "blog_role" {
 
 Use the aws_iam_role_policy resource instead. If Terraform should
 exclusively manage all inline policy associations (the current behavior of
 this argument), use the aws_iam_role_policies_exclusive resource as well.

この状態で inline_policy から aws_iam_role_polcy へ書き換えしてみます.

resource "aws_iam_role" "blog_role" {
  name               = "blog-role"
  assume_role_policy = data.aws_iam_policy_document.ecs_task_assume.json
}
resource "aws_iam_role_policy" "blog_role_inline_policy" {
  name = "blog-role-inline-policy"
  role = aws_iam_role.blog_role.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "s3:*",
        ]
        Effect   = "Allow"
        Resource = [
          "arn:aws:s3:::somebucket",
          "arn:aws:s3:::somebucket/*",
        ]
      },
    ]
  })
}

この状態で terraform plan を実行してみるとインラインポリシーが削除されず新規リソースが追加される結果になりました.

# aws_iam_role_policy.blog_role_inline_policy will be created
+ resource "aws_iam_role_policy" "blog_role_inline_policy" {
    + id          = (known after apply)
    + name        = "blog-role-inline-policy"
    + name_prefix = (known after apply)
    + policy      = jsonencode(
          {
            + Statement = [
                + {
                    + Action   = [
                      + "s3:*",
                      ]
                    + Effect    = "Allow"
                    + Resource  = [
                        + "arn:aws:s3:::somebucket",
                        + "arn:aws:s3:::somebucket/*",
                      ]
                  },
              ]
            + Version   = "2012-10-17"
          }
      )
    + role        = "blog-role"
  }

Plan: 1 to add, 0 to change, 0 to destroy.

この状態だと既存リソースとコンフリクトしてしまうため,import ブロックを追加します.これで既存のリソースに影響が出ない形で Deperecated なコードの対応ができました.

import {
  to = aws_iam_role_policy.blog_role_inline_policy
  id = "blog-role:blog-role-inline-policy"
}

まとめ

aws_iam_roleinline_policy を使用するのが非推奨になったため aws_iam_role_policy に書き換えを行ったときの対応を備忘録にしました.