检查变量是不是存在 - 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】:

我会使用containskeys 执行以下操作

% 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 11中使用列表中的条件

是否可以为不同的资源重用 Terraform 模板,为变量提供不同的值?

Terraform 是不是支持带有少量操作的 CloudFormation 模板

Terraform k8sraw 提供程序错误:产生了一个意外的新值,但在创建模板时现在不存在