terraform applyをすると、意図せずIAMロールがアップデートされてしまう
事象
以下のように2つのポリシーをアタッチするIAMロールをTerraformでデプロイしていました。
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
}
この状態でterraform plan,applyを試すと、このようにアップデートされてしまいます。
コードは変更していないため、No Change
が出る想定でした。
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.
原因
aws_iam_roleのmanaged_policy_arns
とaws_iam_role_policy_attachment
を併用しているため。
対処方法
上記のどちらかに統一します。
こちらはmanaged_policy_arns
に統一したコードです。
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",
+ "${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
- }
深堀りする
terraformのaws_iam_role_policy_attachment
ドキュメントに以下の様に記載がありました。
For a given role, this resource is incompatible with using the aws_iam_role resource managed_policy_arns argument. When using that argument and this resource, both will attempt to manage the role's managed policy attachments and Terraform will show a permanent difference.
併用すると差分を出し続けるらしいです。
managed_policy_arns
側にも注意書きがあります。
どっちを使うのがいいの?
うーん...わかりません。
aws_iam_role_policy_attachment
をポリシー毎に書くことを考えると
managed_policy_arns
のほうが比較的簡潔に書けると思います。
そう考えるとmanaged_policy_arns
に軍配かな...
参考記事[1]によると、外部で設定変更した場合のTerraformの振る舞いに差分があるみたいです。
元にもどってほしいか変更を許容するか...今は判断出来ないですね。
参考
以下の記事を大変参考にさせていただきました。
Discussion