Ошибка синтаксиса JSON в Terraform aws_iam_role_policy

Итак, с Terraform я создаю политику IAM и прикрепляю ее к роли. Я сейчас бегаю:

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

При выполнении кода я могу без проблем инициализировать terraform. При запуске плана terraform я получаю следующую ошибку:

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

person Imran Sandozi    schedule 03.12.2019    source источник
comment
Как выглядит файл шаблона? Возможно, оставлено свободное пространство или скоба / скобка.   -  person Carlo Mencarelli    schedule 03.12.2019


Ответы (1)


При генерации JSON из строковых шаблонов часто встречаются синтаксические ошибки, потому что язык шаблонов не знает синтаксиса JSON, и поэтому вы, как предполагаемый автор, должны позаботиться о том, чтобы все скобки были вложены правильно, не было пропущенных или лишних запятых. , так далее.

Обычно проблем этого типа можно избежать, создав JSON с помощью функции jsonencode Terraform вместо этого:

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
    ]
  })
}

Если определение политики кажется слишком большим для включения в ваш 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.

person Martin Atkins    schedule 04.12.2019