3

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

Terraform v0.12.16
provider.aws v2.40.0
provider.template v2.1.2

执行代码时,我可以毫无问题地初始化 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" {

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

 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")
}
4

1 回答 1

5

从字符串模板生成 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
    ]
  })
}

如果策略定义看起来太大而无法将 inline 包含在您的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}/*"
  })
}

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

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

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

于 2019-12-04T02:37:06.023 回答