如何检查字符串是否包含terraform插值中的子字符串?

JDi*_*teo 10 terraform

如何检查terraform字符串是否包含另一个字符串?

例如,我想特别在名称中使用"tmp"处理terraform工作区(例如,允许在没有快照的情况下删除rds实例),所以像这样:

locals
{
  is_tmp = "${"tmp" in terraform.workspace}"
}
Run Code Online (Sandbox Code Playgroud)

据我所知,substr插值函数没有实现这一点.

小智 25

对于 terraform 0.12.xx 显然你应该使用 regexall 来做到这一点。

来自 terraform 0.12.XX 的手册: regexall() 文档

相关摘录: regexall 还可用于测试特定字符串是否与给定模式匹配,方法是测试结果匹配列表的长度是否大于零。

手册中的示例:

> length(regexall("[a-z]+", "1234abcd5678efgh9"))
2

> length(regexall("[a-z]+", "123456789")) > 0
false
Run Code Online (Sandbox Code Playgroud)

在 terraform 0.12.xx 语法中应用于您的案例的示例应该是这样的:

locals
{
  is_tmp = length(regexall(".*tmp.*", terraform.workspace)) > 0
}
Run Code Online (Sandbox Code Playgroud)

它还在手册中特别说明不要使用“regex”,而是使用regexall。

如果给定的模式根本不匹配,则正则表达式会引发错误。要测试给定模式是否与字符串匹配,请使用 regexall 并测试结果的长度是否大于零。

如上所述,这是因为当您尝试在运行计划时现在已发布的 0.12.xx 的更高版本中使用它时,您实际上会收到异常错误。这就是我发现这一点的方式以及我将新答案发布回此处的原因。


JDi*_*teo 16

您可以使用replace间接检查子字符串,例如

locals
{
  is_tmp = "${replace(terraform.workspace, "tmp", "") != terraform.workspace}"
}
Run Code Online (Sandbox Code Playgroud)

  • 我希望这不是最好的答案.另外据我所知,我无法定义一个terraform`contains`函数(我想我可以定义一个`contains` terraform模块来完成这个,但模块实例化会比复制这个逻辑更冗长). (4认同)
  • 很遗憾`contains` 函数只适用于列表......我有包含分隔符的字符串,所以我可以使用`split` 来测试......但是如果将来我们更改分隔符或其他东西,它会中断......: ( (3认同)

小智 14

Terraformstrcontains在最新版本(v1.5.0)中引入,可以在此处使用:

locals {
    substring_present = strcontains(mystring, mysubstring) # returns True
}
Run Code Online (Sandbox Code Playgroud)


小智 5

与MechaStorm 的答案类似,在 Terraform 0.12.7+ 中,regex如果您的字符串包含特定的子字符串,您可以用于返回布尔值:

locals {
  is_tmp = contains(regex("^(?:.*(tmp))?.*$",terraform.workspace),"tmp")
}
Run Code Online (Sandbox Code Playgroud)

regex查询返回“tmp”之前的任何字符、“tmp”(如果找到)以及“tmp”之后的任何字符的捕获组列表。然后,contains在列表中查找“tmp”并返回 true 或 false。