Terraformを使っている際、意図せずIAMロールがアップデートされてしまう
事象
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
}
気になる記事が、
aws_iam_role_policy_attachment
とmanaged_policy_arns
の併用は推奨されないという内容
こんな記載がありました
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
で統一してみる
併用しているのがマズそうなので、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.
になりました
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.
になりました
どっちを使う
うーん...正直どちらでも問題なさそう...
ポリシー毎にaws_iam_role_policy_attachment
を増やさなくてはいけないことを考えると
managed_policy_arns
のほうが簡潔に記載出来ると思います。
そう考えるとmanaged_policy_arns
に軍配かな
こちらの記事によると、外部で設定変更した場合のTerraformの振る舞いに差分があるみたいです。
元にもどってほしいか変更を許容するか...うーんわからん!!!
使っていく中で判断しましょう
結論
aws_iam_role_policy_attachment
とaws_iam_role
のmanaged_policy_arns
は併用せず、どちらかに統一する