全く大した話ではなく、TerraformでEC2にIAMポリシーを割り当てようとコードを書いていたら掲題のエラーが出力されて少し調べたのでメモ。
Terraform: Error creating IAM Role. MalformedPolicyDocument: Has prohibited field Resource
使っているTerraformのバージョンは0.12.6
その時のTerraformのコードはこんな感じです。
resource "aws_iam_role" "this" {
name = "iam_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": [
"eks:UpdateClusterVersion",
"eks:DescribeCluster",
"eks:ListClusters"
],
"Resource": "*"
}
]
}
EOF
resource "aws_iam_instance_profile" "this" {
name = "profile"
role = aws_iam_role.this.name
}
よくよく考えるとassume-roleブロックに直接ポリシーを書いているのはまあ、違和感があるかも。。。
とか考えてました。
結論
aws_iam_roleには信頼ポリシーと呼ばれる記法で委譲する対象を指定しなければならない。
元々期待していたポリシーに関する記述はaws_iam_role_policyと言うresourceに書きましょう。
認証、認可やassume-roleの概念について雰囲気でしか理解していなかったため、
うっかりassume-roleに直接ポリシー書いてしまっていたと言うチョンボなお話でした。
下記の様なコードに修正。
resource "aws_iam_role" "operation_iam_role" {
name = "iam_role"
// ここに権限を委譲するポリシーを書く
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
// このresourceを追加してポリシーを記載する
resource "aws_iam_role_policy" "this" {
name = "iam_role_policy"
role = aws_iam_role.this.id
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": [
"eks:UpdateClusterVersion",
"eks:DescribeCluster",
"eks:ListClusters"
],
"Resource": "*"
}
]
}
EOF
}
resource "aws_iam_instance_profile" "this" {
name = "profile"
role = aws_iam_role.this.name
}
無事にapplyし、EC2にIAM-Roleを割り当てる事ができました。