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

时间:2020-05-23 11:13:17

标签: amazon-web-services terraform amazon-iam terraform-provider-aws

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

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

我在哪里出错?请不要发布指向相同问题的链接。我不明白,如果有错误,请问您有没有错误的例子? 感谢您的关注。

2 个答案:

答案 0 :(得分:1)

一个问题是,您有两个带有 Sid 相同的语句:ExpressionMethodAttribute

Sid必须为唯一。来自docs

在IAM中,JSON策略中的Sid值必须唯一

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

assume_role_policy

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

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

答案 1 :(得分:1)

现有代码有什么问题?

aws_iam_role resource assume_role_policy 属性不是用于授予对除 sts:AssumeRole 以外的调用API的权限:

assume_role_policy-(必填)该策略授予实体承担角色的权限。

注意:此假定_角色_策略与标准IAM策略非常相似,但略有不同,并且不能使用aws_iam_policy资源。但是,它可以使用aws_iam_policy_document数据源,有关如何工作的信息,请参见下面的示例。

我该如何解决?

因此,假设您希望该角色可由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留在空白处,可以缩进JSON以提高可读性:

Terraform还接受由<<-序列引入的indented heredoc string变体:

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 = [
      "*",
    ]
  }
}