我在Terraform中为AWS资源定义了一个策略,如下所示:
device-status-policy = <<EOF
{"Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iot:Connect", "Resource": "arn:aws:iot:us-west-2:foobaraccountid:client/device-status-qa*" }, { "Effect": "Allow", "Action": [ "iot:Publish", "iot:Receive", "iot:Subscribe" ] }
EOF
我希望其中的Resource部分是一个变量,像这样(伪代码)
device-status-policy = <<EOF
{"Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iot:Connect", "Resource": "$SOMEVAR/device-status-qa*" }, { "Effect": "Allow", "Action": [ "iot:Publish", "iot:Receive", "iot:Subscribe" ] }
EOF
感谢您的帮助。谢谢。
答案 0 :(得分:2)
将$SOMEVAR
更改为${SOMEVAR}
。
请查看Terraform string interpolation syntax。
此外,我强烈建议使用数据源aws_iam_policy_document定义IAM策略,而不是使用此处的文档。
答案 1 :(得分:2)
因此,我唯一可行的选择是:
创建文件,例如具有以下内容的policy.tpl:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:Connect",
"Resource": "${SOMEVAR}/device-status-qa*"
},
{
"Effect": "Allow",
"Action": [
"iot:Publish",
"iot:Receive",
"iot:Subscribe"
]
}
]
}
该策略文件包含您需要的变量。
然后,您只需引用它并以以下方式传递变量即可:
device-status-policy = templatefile("file.tpl", { SOMEVAR = var.your_terraform_variable})
希望有帮助
答案 2 :(得分:1)
使用${ ... }
语法的字符串内插是从文字JSON字符串起的最小变化,但是如果例如使用插入的字符串包含JSON解析器可能会误解的反斜杠和引号。
Terraform的jsonencode
函数可以很好地折中,因为Terraform的对象语法与JSON非常相似,因此保留了快速了解其生成的JSON结构的能力,同时允许任意Terraform表达式,其结果将使用正确的JSON语法自动编码:
device-status-policy = jsonencode({
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:Connect",
"Resource": "${SOMEVAR}/device-status-qa*"
},
{
"Effect": "Allow",
"Action": [ "iot:Publish", "iot:Receive", "iot:Subscribe" ]
}
]
})
请注意,上面使用的是Terraform语言对象语法的一种变体形式,该语法使用冒号而不是等号;两者都是有效的,在这里使用冒号可以使输入类似于JSON,因此可以轻松修改您已经编写的JSON(就像我在这里所做的那样),而无需进行大量重写。
但是,"${SOMEVAR}/device-status-qa*"
序列被Terraform理解为带引号的模板表达式而不是文字字符串,因此它将评估SOMEVAR
并将结果包括在Resource
值中之前使用JSON语法序列化整个结果字符串。尽管在这种特定情况下似乎不太可能,但是如果SOMEVAR
结果是包含"
的字符串,则JSON编码将自动将其转义为\"
以确保结果是有效的语法。
对于更大的数据结构,它可以提高可读性以将其分解到一个单独的文件中,the templatefile
function文档还包括了calling jsonencode
from inside an external template的一些示例,结果相似。