繁体   English   中英

Terraform AWS IAM 角色“inline_policy.0.policy”包含使用 ${file xyz} 和 jsonencode 的无效 JSON 策略

[英]Terraform AWS IAM Role “inline_policy.0.policy” contains an invalid JSON policy using ${file xyz} and jsonencode

请看下面。 首先,只有承担角色政策,它才有效。 如果我删除内联策略,它就会全部生效。 当留在其中时,(它看起来像这样。)它不会验证。 我正在使用 Terragrunt,但我认为这是一个 Terraform 错误。

resource "aws_iam_role" "test_role" {
  name   = "my_test_role"
  assume_role_policy = jsonencode("${file("..//Policies//policy_assume_role.json")}")
  inline_policy {
    name = "inline_s3_policy"
    policy = jsonencode("${file("..//Policies//policy_s3_bucket.json")}")
  }
}

然后我的 policy_s3_bucket.json 看起来像这样

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": ["arn:aws:s3:::company-terragrunt-terraform-state-123456789-us-east-1"]
    },
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject"],
      "Resource": ["arn:aws:s3:::company-terragrunt-terraform-state-123456789-us-east-1/*"]
    }
  ]
}

我得到 - ““inline_policy.0.policy”包含无效的 JSON 策略”……但是 JSON 是有效的。 我配置的用户确实有权访问这些存储桶。 此外,假设角色策略在没有 s3 内联的情况下也能正常工作。 承担角色策略 json 看起来格式相同,我正在以相同的方式提取它。

在您的配置中,您似乎将file function 的结果传递到jsonencode function。

file function 的结果始终是表示文件的 UTF-8 编码内容的字符串,因此如果您的文件包含已编码的 JSON,那么它将返回一个包含 JSON 的字符串。

如果您将字符串传递给jsonencode ,那么它将生成一个 JSON 格式的字符串,而 IAM 策略需要 JSON object,因此 API 将返回一个错误,如此处所示。

更具体地说,您当前的配置会将policy设置为类似以下内容(为简洁起见被截断):

"{\n  \"Version\": \"2012-10-17\"m\n  \"Statement\": ..."

如果您知道您的外部文件已经包含有效的 JSON,那么您可以将file的结果直接分配给policy参数,如下所示:

resource "aws_iam_role" "test_role" {
  name               = "my_test_role"
  assume_role_policy = file("${path.module}/../Policies/policy_assume_role.json")

  inline_policy {
    name   = "inline_s3_policy"
    policy = file("${path.module}/../Policies/policy_s3_bucket.json")
  }
}

如果您希望 Terraform 解析 JSON 并对其重新编码——这意味着 Terraform 将首先检查 JSON 内容是否在本地有效,并且始终以一致的缩小形式生成它,您也可以将file结果传递给首先是jsondecode ,然后将该结果传递给jsonencode ,从而通过 Terraform 语言类型系统“往返”并再次返回到 JSON:

resource "aws_iam_role" "test_role" {
  name               = "my_test_role"
  assume_role_policy = jsonencode(jsondecode(file("${path.module}/../Policies/policy_assume_role.json")))

  inline_policy {
    name   = "inline_s3_policy"
    policy = jsonencode(jsondecode(file("${path.module}/../Policies/policy_s3_bucket.json")))
  }
}

然而,这将是一种非常不寻常的方法,因此如果您采用它,那么我建议包括一条注释来解释您为什么这样做,以便未来的读者能够理解为什么包含这种看似冗余的转换。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM