0

我正在尝试使用 Terraform 在 AWS 中构建云基础设施。我想通过templatefileterraform 的功能为使用基于属性的授权 (ABAC) 的 S3 存储桶添加策略。我的问题是 terraform 和 AWS 使用的变量语法是相同的 ( ${...})。

这是策略模板:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowReadRole1",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::${bucketName}/*",
            "Effect": "Allow",
            "Principal": "*",
            "Condition": {
                "s3:ExistingObjectTag/myid": "${aws:PrincipalTag/myid}"
            }
        }
    ]
}

terrafrom 文件的相关部分是:

resource "aws_s3_bucket_policy" "mybuckets-policy" {
  bucket = aws_s3_bucket.mybuckets[count.index].bucket
  policy = templatefile("${path.module}/bucket-policy.json", {
    bucketName = aws_s3_bucket.mybuckets[count.index].bucket
  })
  count = 2
}

所以我想要的是${bucketName}模板的一部分被 terraform 替换,同时保持 AWS 表达式${aws:PrincipalTag/user-id}在适当的位置。但是在上面的配置上运行 terraform 会导致错误消息

调用函数“模板文件”失败:./bucket-policy.json:14,49-50:插值表达式后的额外字符;需要一个右大括号来结束插值表达式,但发现了额外的字符..

如果我在模板中放置另一个项目${foobar}而没有为其指定值,则错误消息是

“vars”参数的值无效:vars 映射不包含键“foobar”,在 ./bucket-policy.json:11,30-36 中引用。

如何让 terraform 对模板文件进行部分评估,同时保持所有其他项目不变?

4

1 回答 1

2

在上面的示例中,语法 ${} 将导致 Terraform 尝试将字段评估为插值函数。由于您想按字面意思使用此值而不是作为插值函数,因此需要使用两个 $ 符号进行双重转义。

$${aws:PrincipalTag/user-id}

于 2020-04-28T12:19:30.060 回答