Terraform aws_iam_role_policy 中的 JSON 语法错误

Imr*_*ozi 3 amazon-web-services terraform terraform-template-file terraform-provider-aws

因此,通过 Terraform,我创建了一个 IAM 策略并将其附加到一个角色。我目前正在运行:

Terraform v0.12.16
provider.aws v2.40.0
provider.template v2.1.2
Run Code Online (Sandbox Code Playgroud)

执行代码时,我可以毫无问题地初始化 terraform。运行 terraform plan 时,出现以下错误:

Error: "policy" contains an invalid JSON: invalid character '}' looking for beginning of value

  on ec2-iam.tf line 8, in resource "aws_iam_role_policy" "s3_ec2_policy":
   8: resource "aws_iam_role_policy" "s3_ec2_policy" {
Run Code Online (Sandbox Code Playgroud)

我陷入了这个错误。任何意见将是有益的。下面是我的代码:

 data "template_file" "s3_web_policy" {
  template = file("scripts/iam/web-ec2-policy.json")
  vars = {
    s3_bucket_arn = "arn:aws:s3:::${var.my_app_s3_bucket}/*"
  }
}

resource "aws_iam_role_policy" "s3_ec2_policy" {
  name = "s3_ec2_policy"
  role = aws_iam_role.s3_ec2_role.id

  policy = data.template_file.s3_web_policy.rendered
}

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

  assume_role_policy = file("scripts/iam/web-ec2-assume-role.json")
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ins 7

从字符串模板生成 JSON 时经常会遇到语法错误,因为模板语言不支持 JSON 语法,因此作为模板作者必须注意确保括号全部正确嵌套,没有丢失或多余的逗号, ETC。

通常可以通过使用Terraform 的jsonencode函数生成 JSON 来避免此类问题:

resource "aws_iam_role_policy" "s3_ec2_policy" {
  name = "s3_ec2_policy"
  role = aws_iam_role.s3_ec2_role.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      # etc, etc
    ]
  })
}
Run Code Online (Sandbox Code Playgroud)

如果策略定义看起来太大而无法包含在块中resource,您仍然可以根据需要将其分解到单独的模板文件中:

resource "aws_iam_role_policy" "s3_ec2_policy" {
  name = "s3_ec2_policy"
  role = aws_iam_role.s3_ec2_role.id

  policy = templatefile("${path.module}/scripts/iam/web-ec2-policy.json.tmpl", {
    s3_bucket_arn = "arn:aws:s3:::${var.my_app_s3_bucket}/*"
  })
}
Run Code Online (Sandbox Code Playgroud)

...但是在模板内部,而不是使用单独的模板插值,只需将整个模板编写为对 的单个调用jsonencode,如下所示:

${jsonencode({
  Version = "2012-10-17"
  Statement = [
    {
      # ...
      Resource = s3_bucket_arn
      # ...
    },
    # etc, etc
  ]
})}
Run Code Online (Sandbox Code Playgroud)

请注意,template_file数据源适用于 Terraform 0.11 及更早版本,在 Terraform 0.12 中仅用于向后兼容。您应该改用templatefile函数,它具有相同的目的,但直接集成到 Terraform 语言中。