4

我正在尝试使用 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失败。

如何使用字符串模板检查变量是否存在?

4

2 回答 2

8

如果您使用的是 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因此,由于其相对清晰,我认为上述用法是合理的,但任何一种方式都应该有效。

于 2020-02-14T17:50:24.170 回答
1

我会做类似以下的事情,使用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可以检查关键内容的 JSON。

我用以下代码对此进行了测试

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 {

}

于 2020-02-14T14:02:15.273 回答