创建 IAM 角色时出错。 MalformedPolicyDocument:具有禁止的字段 Resource。地貌

Error creating IAM Role. MalformedPolicyDocument: Has prohibited field Resource. Terraform

我看过几个链接,但我必须看一个例子。 我有:

resource "aws_iam_role" "role" {
  name = "role"

  assume_role_policy = <<-EOF
{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Sid": "Stmt1590217939125",
        "Action": "s3:*",
        "Effect": "Allow",
        "Resource": "arn:aws:s3:::wwe"
      },
      {
        "Sid": "Stmt1590217939125",
        "Action": "s3:*",
        "Effect": "Allow",
        "Resource": "arn:aws:s3:::wwe/*"
      },
      {
        "Sid": "Stmt1577967806846",
        "Action": [
          "secretsmanager:DescribeSecret",
          "secretsmanager:GetRandomPassword",
          "secretsmanager:GetResourcePolicy",
          "secretsmanager:GetSecretValue",
          "secretsmanager:ListSecretVersionIds",
          "secretsmanager:ListSecrets"
        ],
        "Effect": "Allow",
        "Resource": "*"
      }
    ]
}
  EOF
  tags = {
    Name        = wwe
    Environment = STAGE
  }
}

我做的时候,

terraform apply

我看到了这个:

  # aws_iam_role.role will be created
  + resource "aws_iam_role" "role" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action   = "s3:*"
                      + Effect   = "Allow"
                      + Resource = "arn:aws:s3:::wwe"
                      + Sid      = "Stmt1590217939125"
                    },
                  + {
                      + Action   = "s3:*"
                      + Effect   = "Allow"
                      + Resource = "arn:aws:s3:::wwe/*"
                      + Sid      = "Stmt1590217939125"
                    },
                  + {
                      + Action   = [
                          + "secretsmanager:DescribeSecret",
                          + "secretsmanager:GetRandomPassword",
                          + "secretsmanager:GetResourcePolicy",
                          + "secretsmanager:GetSecretValue",
                          + "secretsmanager:ListSecretVersionIds",
                          + "secretsmanager:ListSecrets",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                      + Sid      = "Stmt1577967806846"
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + max_session_duration  = 3600
      + name                  = "role"
      + path                  = "/"
      + tags                  = {
          + "Environment" = "STAGE"
          + "Name"        = "wwe"
        }
      + unique_id             = (known after apply)
    }

之后,当我写 yes 时,我看到:

Error: Error creating IAM Role role: MalformedPolicyDocument: Has prohibited field Resource
        status code: 400

我哪里出错了?请不要 post 链接到相同的问题。我不明白,我哪里有错误,如果可能的话,你能写一个我有错误的例子吗? 感谢您的关注。

一个问题是您有两个具有 相同 Sid 的语句:Stmt1590217939125

Sids 必须唯一。来自 docs:

In IAM, the Sid value must be unique within a JSON policy.

第二个问题是 assume_role_policy 适用于 信任策略 。信任策略 没有资源 。它们有不同的形式。对于 instance:

 assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}

要将您的策略​​添加到角色,必须使用 aws_iam_role_policy_attachment。例如,您可以这样做:

resource "aws_iam_policy" "policy" {
  name = "my-role"
   description = "My policy"

  policy = <<-EOF
{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Sid": "Stmt1590217939128",
        "Action": "s3:*",
        "Effect": "Allow",
        "Resource": "arn:aws:s3:::wwe"
      },
      {
        "Sid": "Stmt1590217939125",
        "Action": "s3:*",
        "Effect": "Allow",
        "Resource": "arn:aws:s3:::wwe/*"
      },
      {
        "Sid": "Stmt1577967806846",
        "Action": [
          "secretsmanager:DescribeSecret",
          "secretsmanager:GetRandomPassword",
          "secretsmanager:GetResourcePolicy",
          "secretsmanager:GetSecretValue",
          "secretsmanager:ListSecretVersionIds",
          "secretsmanager:ListSecrets"
        ],
        "Effect": "Allow",
        "Resource": "*"
      }
    ]
}
EOF
}

resource "aws_iam_role_policy_attachment" "test-attach" {
  role       = "${aws_iam_role.role.name}"
  policy_arn = "${aws_iam_policy.policy.arn}"
}

现有代码有什么问题?

aws_iam_role resourceassume_role_policy 属性不用于授予调用除 sts:AssumeRole[= 以外的 API 的权限37=]:

assume_role_policy - (Required) The policy that grants an entity permission to assume the role.

NOTE: This assume_role_policy is very similar but slightly different than just a standard IAM policy and cannot use an aws_iam_policy resource. It can however, use an aws_iam_policy_document data source, see example below for how this could work.

我该如何解决?

因此,假设您希望 EC2 承担此角色,您将使用 aws_iam_role 来声明 IAM 角色及其 assume_role_policy:

resource "aws_iam_role" "role" {
  name = "role"

  assume_role_policy = <<-EOF
  EOF
  tags = {
    Name        = wwe
    Environment = STAGE
  }
}

然后使用 aws_iam_role_policy 将内联策略附加到您希望授予该角色的 IAM 操作(以及资源​​和可能的条件):

resource "aws_iam_role_policy" "policy" {
  name = "policy"
  role = aws_iam_role.role.id

  policy = <<-EOF
  {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Action": "s3:*",
          "Effect": "Allow",
          "Resource": "arn:aws:s3:::wwe"
        },
        {
          "Action": "s3:*",
          "Effect": "Allow",
          "Resource": "arn:aws:s3:::wwe/*"
        },
        {
          "Action": [
            "secretsmanager:DescribeSecret",
            "secretsmanager:GetRandomPassword",
            "secretsmanager:GetResourcePolicy",
            "secretsmanager:GetSecretValue",
            "secretsmanager:ListSecretVersionIds",
            "secretsmanager:ListSecrets"
          ],
          "Effect": "Allow",
          "Resource": "*"
        }
      ]
  }
  EOF
}

你不需要把你的 JSON 塞进边距,它可以缩进以提高可读性:

Terraform also accepts an indented heredoc string variant that is introduced by the <<- sequence:

block {
  value = <<-EOT
  hello
    world
  EOT
}

我建议使用 aws_iam_policy_document 数据源来构建您的 IAM 策略。它避免了令人讨厌的 JSON 怪癖(比如没有尾随逗号)并且更好地支持您需要在构建策略时使用变量的场景(在所有情况下都很难正确转义它们):

resource "aws_iam_role_policy" "policy" {
  name = "policy"
  policy = data.aws_iam_policy_document.policy_doc.json
}

data "aws_iam_policy_document" "policy_doc" {
  statement {
    actions = [
      "s3:*",
    ]

    resources = [
      "arn:aws:s3:::wwe",
    ]
  }

  statement {
    actions = [
      "s3:*",
    ]

    resources = [
      "arn:aws:s3:::wwe/*",
    ]
  }

  statement {
    actions = [
      "secretsmanager:DescribeSecret",
      "secretsmanager:GetRandomPassword",
      "secretsmanager:GetResourcePolicy",
      "secretsmanager:GetSecretValue",
      "secretsmanager:ListSecretVersionIds",
      "secretsmanager:ListSecrets",
    ]

    resources = [
      "*",
    ]
  }
}