因此,对于 Terraform,我正在创建一个 IAM 策略并将其附加到角色。我目前正在运行:
Terraform v0.12.16
provider.aws v2.40.0
provider.template v2.1.2
执行代码时,我能够毫无问题地初始化地形。运行地形规划时,出现以下错误:
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")
}
从字符串模板生成 JSON 时经常会遇到语法错误,因为模板语言不知道 JSON 语法,因此您作为临时作者必须注意确保括号都正确嵌套,没有丢失或多余的逗号等。
通常,您可以通过使用 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
]
})
}
如果策略定义看起来太大而无法包含在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 语言中。