我正在尝试使用Terraform在AWS中构建云基础设施。我想通过terraform的templatefile
函数为S3 bucket添加一个策略,该策略使用基于属性的授权(ABAC(。我的问题是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会导致错误消息
调用函数"templatefile"失败:/bucketpolicy.json:14,49-50:额外插值表达式后的字符;应使用大括号结束插值表达式,但找到了额外的字符。。
如果我在模板中放入另一个项${foobar}
而没有为其指定值,则错误消息为
"vars"参数的值无效:vars映射不包含键"foobar",引用于/bucket policy.json:11,30-36.
如何使terraform在保留所有其他项目不变的情况下对模板文件进行部分评估?
在上面的例子中,语法${}将导致Terraform尝试将字段求值为插值函数。由于您希望从字面上使用该值,而不是将其用作插值函数,因此需要使用两个$符号对其进行双转义。
$${aws:PrincipalTag/user-id}