"jsonencode" 只需要 1 个参数

"jsonencode" expects only 1 argument(s)

我正在尝试改造 AWS 角色。我按照这个例子,他们只附加了一个 json 政策:

resource "aws_iam_policy" "policy" {
  name        = "test_policy"
  path        = "/"
  description = "My test policy"

  # Terraform's "jsonencode" function converts a
  # Terraform expression result to valid JSON syntax.
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "ec2:Describe*",
        ]
        Effect   = "Allow"
        Resource = "*"
      },
    ]
  })
}

不过,我想附上两项政策。我在两者之间用逗号尝试了这个:

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

  assume_role_policy = jsonencode(

    {
      "Version" : "2012-10-17",
      "Statement" : [
        {
          "Effect" : "Allow",
          "Action" : [
            "s3:*",
            "s3-object-lambda:*"
          ],
          "Resource" : "*"
        }
      ]
    },
    {
      "Version" : "2012-10-17",
      "Statement" : [
        {
          "Effect" : "Allow",
          "Action" : [
            "logs:CreateLogGroup",
            "logs:CreateLogStream",
            "logs:PutLogEvents"
          ],
          "Resource" : "*"
        }
      ]
    }

  )

然而,这给出了一个错误:

Function "jsonencode" expects only 1 argument(s).

我还能如何附加多个保单?

这是因为您的政策 json 格式错误。您需要将两个策略包装在一个数组中,如下所示。

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

  assume_role_policy = jsonencode(
    [
      {
        "Version" : "2012-10-17",
        "Statement" : [
          {
            "Effect" : "Allow",
            "Action" : [
              "s3:*",
              "s3-object-lambda:*"
            ],
            "Resource" : "*"
          }
        ]
      },
      {
        "Version" : "2012-10-17",
        "Statement" : [
          {
            "Effect" : "Allow",
            "Action" : [
              "logs:CreateLogGroup",
              "logs:CreateLogStream",
              "logs:PutLogEvents"
            ],
            "Resource" : "*"
          }
        ]
      }
    ]
  )

assume_role_policy 参数只需要一个 单个 IAM 策略文档,但该文档可能包含多个 语句 如果您需要声明对不同资源的多重影响。

请注意,尽管 assume_role_policy 用于指定允许哪些其他 IAM 委托人担任该角色。它 指定角色本身授予的访问权限。因此,在代入角色策略中为 sts:AssumeRolests:AssumeRoleWithSAMLsts:AssumeRoleWithWebIdentity 以外的操作声明策略没有用。

(我在 中写了更多关于 AssumeRole 的细节。)

鉴于您共享的策略内容,我预计您的意图是将一个策略与两个语句与该角色相关联,以便承担该角色将授予该访问权限。为此,您需要使用 the aws_iam_role_policy resource typeaws_iam_role,首先声明角色,然后声明与之关联的策略:

resource "aws_iam_role" "example" {
  name = "name"

  # You will also need to set assume_role_policy to declare
  # what can assume this role, but there isn't enough
  # information in your question to know what policy would
  # be appropriate for that.
}

resource "aws_iam_role_policy" "example" {
  name = aws_iam_role.example.name

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect   = "Allow"
        Action   = [
          "s3:*",
          "s3-object-lambda:*",
        ]
        Resource = "*"
      },
      {
        Effect   = "Allow"
        Action   = [
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents",
        ]
        Resource = "*"
      },
    ]
  })
}

output "role_arn" {
  value = aws_iam_role.example.arn

  # The role ARN won't be fully usable until
  # the policy is attached to it, so we must
  # declare this additional dependency to get
  # correct ordering of operations.
  depends_on = [aws_iam_role_policy.example]
}

请注意 aws_iam_role_policy.example 中的 policy 表达式只有一个策略 文档 ,但该文档有两个 语句 每个独立地允许一组动作。在这种情况下,相当于将所有这些操作放在一个语句中,但我假设您将它们分开,因为实际上它们彼此并不相似。

为同一角色声明多个 aws_iam_role_policy 也是有效的,如果您想将角色的声明与授予不同的策略分开,这会很有用,但在这种情况下(其中同一个模块无论如何都在声明)没有理由增加这种复杂性。