首页 > 解决方案 > Terraform template_file 空 Json 验证

问题描述

我的 Terrform 代码如下所示。这里我的参数文件有些时候有值,大部分时间都是空的 JSON{}

resource "azurerm_policy_assignment" "example" {
  name                 = "example-policy-assignment"
  scope                = azurerm_resource_group.example.id
  policy_definition_id = azurerm_policy_definition.example.id
  description          = "Policy Assignment created via an Acceptance Test"
  display_name         = "My Example Policy Assignment"

  parameters           = "${data.template_file.policy_parameters_file.rendered}"

所以我需要做一些验证来检查我的参数文件是否为空 json 然后我需要分配一个空字符串。

我尝试如下,但它不工作

"${data.template_file.policy_parameters_file.rendered}" == {} ? "" : "${data.template_file.policy_parameters_file.rendered}"

需要进行此验证,因为状态文件已经将参数值设为“”。现在,如果我运行 terraform 计划,它显示为

parameters           = jsonencode({}) # forces replacement 

这使得强制替换。

如果我将参数硬编码为“”,一切顺利。所以为了处理这个问题,我需要找到一种方法来处理参数文件中空 json 的验证。如果 json 为空,我需要传递为“”

标签: terraformterraform-provider-azure

解决方案


听起来您有一个生成 JSON 的模板,但有时会生成一个空的 JSON 对象,在这种特殊情况下,您宁愿完全不设置此参数,而不是将其设置为字面意义"{}"上的 .

如果是这样,我认为您尝试的问题是您将字符串"{}"与真正的空对象进行了比较{},因为字符串和对象不可比较,所以它总是会返回 false。(作为一般规则,==总是返回false不同类型的值。)

如果您知道空对象大小写始终是 string "{}",而不是任何其他等效的 JSON,例如"{ }"(大括号之间有空格),那么您可以编写一个与您编写的表达式非常相似的表达式,除了与那个进行比较字符串代替:

  parameters = (
    data.template_file.policy_parameters_file.rendered != "{}" ?
    data.template_file.policy_parameters_file.rendered :
    null
  )

如果您想更健壮一点并捕获 JSON 对象的任何有效编码,您可以编写一个稍微复杂的表达式,如下所示:

  parameters = (
    length(jsondecode(data.template_file.policy_parameters_file.rendered)) > 0 ?
    data.template_file.policy_parameters_file.rendered :
    null
  )

这会将 JSON 再次解码为真实对象,然后测试它是否具有至少一个属性。


请注意,template_file对于使用 Terraform v0.12.0 或更高版本的任何人,不推荐使用该数据源。虽然不需要离开该功能以获得如上所述的工作结果,但我建议还计划在将来迁移到templatefile功能,因为它将持续支持并正确集成到Terraform 语言,因此它可以避免来自template_file在外部插件中实现的数据源的各种奇怪的怪癖。


推荐阅读