检查变量是不是存在 - Terraform 模板语法
Posted
技术标签:
【中文标题】检查变量是不是存在 - Terraform 模板语法【英文标题】:Check if variable exists - Terraform template syntax检查变量是否存在 - Terraform 模板语法 【发布时间】:2020-05-30 03:25:33 【问题描述】:我正在尝试使用 terraform 模板语法检查模板文件中是否存在变量,但出现 This object does not have an attribute named "proxy_set_header
错误。
$ cat nginx.conf.tmpl
% for location in jsondecode(locations)
location $location.path
% if location.proxy_set_header
proxy_set_header $location.proxy_set_header;
% endif
% endfor
我尝试使用if location.proxy_set_header != ""
和if location.proxy_set_header
没有成功。
如何使用字符串模板检查变量是否存在?
【问题讨论】:
【参考方案1】:如果您使用的是 Terraform 0.12.20 或更高版本,则可以使用新功能 can
简洁地编写如下检查:
% for location in jsondecode(locations)
location $location.path
% if can(location.proxy_set_header)
proxy_set_header $location.proxy_set_header;
% endif
% endfor
can
函数如果给定表达式可以无错误地计算,则返回 true。
文档确实建议在大多数情况下首选try
,但在这种特殊情况下,如果该属性不存在,您的目标是什么都不显示,因此我认为与try
等效的方法是,对于未来的读者来说更难理解:
% for location in jsondecode(locations)
location $location.path
$ try("proxy_set_header $location.proxy_set_header;", "")
% endfor
除了(主观上)对意图更加不透明之外,这忽略了 try
文档中关于仅将其用于属性查找和类型转换表达式的建议。因此,我认为上面的 can
用法是合理的,因为它相对清晰,但任何一种方式都应该有效。
【讨论】:
【参考方案2】:我会使用contains
和keys
执行以下操作
% for location in jsondecode(locations)
location $location.path
% if contains(keys(location), "proxy_set_header")
proxy_set_header $location.proxy_set_header;
% endif
% endfor
解析后的 JSON 本质上变成了 map
,可以检查关键内容。
我用以下代码对此进行了测试
data "template_file" "init"
template = file("$path.module/file.template")
vars =
locations = <<DOC
[
"path": "foo",
"proxy_set_header": "foohdr"
,
"path": "bar"
]
DOC
output "answer"
value = data.template_file.init.rendered
它有以下输出
Outputs:
answer =
location foo
proxy_set_header foohdr;
location bar
【讨论】:
以上是关于检查变量是不是存在 - Terraform 模板语法的主要内容,如果未能解决你的问题,请参考以下文章
检查模板中是不是存在变量,如果不存在则不会在记录器中导致错误
检查 EJS 模板中是不是存在变量的正确方法是啥(使用 ExpressJS)?
是否可以为不同的资源重用 Terraform 模板,为变量提供不同的值?