Closed8

Terraformを使っている際、意図せずIAMロールがアップデートされてしまう

not75743not75743

事象

terraform apply後、再度plan,applyを試みるとアップデートされてしまう。
コードの変更はしていない。

plan,apply

Terraform will perform the following actions:

  # module.app.aws_iam_role.task_execution_role will be updated in-place
  ~ resource "aws_iam_role" "task_execution_role" {
        id                    = "fargate-nginx_dev_task_execution_role"
      ~ managed_policy_arns   = [
          - "arn:aws:iam::xxxxxxxxxxxx:policy/GetParameterStore",
            # (1 unchanged element hidden)
        ]
        name                  = "fargate-nginx_dev_task_execution_role"
        tags                  = {}
        # (9 unchanged attributes hidden)
    }

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

コード

## TaskExecutionRole

data "aws_ssm_parameter" "securestring" {
  name = "/test/secret-string"
  with_decryption = "true"
}

data "aws_iam_policy_document" "GetParameterStore" {
  statement {
    effect = "Allow"
    actions = [
      "ssm:GetParameters",
    ]
    resources = [
      "${data.aws_ssm_parameter.securestring.arn}",
    ]
  }
}

resource "aws_iam_policy" "GetParameterStore" {
  name   = "GetParameterStore"
  path   = "/"
  policy = data.aws_iam_policy_document.GetParameterStore.json
}

resource "aws_iam_role" "task_execution_role" {
  name = "${var.system_name}_${var.environment}_task_execution_role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect    = "Allow"
        Principal = { Service = "ecs-tasks.amazonaws.com" }
        Action    = "sts:AssumeRole"
      }
    ]
  })
  managed_policy_arns = [
    "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy",
  ]
}

resource "aws_iam_role_policy_attachment" "GetParameterStore" {
    role = aws_iam_role.task_execution_role.name
    policy_arn = aws_iam_policy.GetParameterStore.arn
}
not75743not75743

managed_policy_arnsで統一してみる

併用しているのがマズそうなので、managed_policy_arnsに統一してみます。

resource "aws_iam_role" "task_execution_role" {
  name = "${var.system_name}_${var.environment}_task_execution_role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect    = "Allow"
        Principal = { Service = "ecs-tasks.amazonaws.com" }
        Action    = "sts:AssumeRole"
      }
    ]
  })
  managed_policy_arns = [
    "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy",
+    "${aws_iam_policy.GetParameterStore.arn}"
  ]
}

- resource "aws_iam_role_policy_attachment" "GetParameterStore" {
-     role = aws_iam_role.task_execution_role.name
-     policy_arn = aws_iam_policy.GetParameterStore.arn
- }

確認

無事No changes.になりました

not75743not75743

aws_iam_role_policy_attachmentで統一してみる

こちらも試してみます

resource "aws_iam_role" "task_execution_role" {
  name = "${var.system_name}_${var.environment}_task_execution_role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect    = "Allow"
        Principal = { Service = "ecs-tasks.amazonaws.com" }
        Action    = "sts:AssumeRole"
      }
    ]
  })
-  managed_policy_arns = [
-    "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy",
-    "${aws_iam_policy.GetParameterStore.arn}"
-  ]
}

+ resource "aws_iam_role_policy_attachment" "GetParameterStore" {
+     role = aws_iam_role.task_execution_role.name
+     policy_arn = aws_iam_policy.GetParameterStore.arn
+ }

+ resource "aws_iam_role_policy_attachment" "ECSTaskExecutionRolePolicy" {
+     role = aws_iam_role.task_execution_role.name
+     policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
+ }

確認

こちらも無事No changes.になりました

not75743not75743

どっちを使う

うーん...正直どちらでも問題なさそう...
ポリシー毎にaws_iam_role_policy_attachmentを増やさなくてはいけないことを考えると
managed_policy_arnsのほうが簡潔に記載出来ると思います。
そう考えるとmanaged_policy_arnsに軍配かな

こちらの記事によると、外部で設定変更した場合のTerraformの振る舞いに差分があるみたいです。
元にもどってほしいか変更を許容するか...うーんわからん!!!
https://qiita.com/hmdsg/items/7862213637fc4c3d9a3f

使っていく中で判断しましょう

not75743not75743

結論

aws_iam_role_policy_attachmentaws_iam_rolemanaged_policy_arnsは併用せず、どちらかに統一する

このスクラップは2023/06/11にクローズされました