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

时间:2017-11-11 22:31:35

标签: terraform

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

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

locals
{
  is_tmp = "${"tmp" in terraform.workspace}"
}

据我所知,substr interpolation function并没有达到目的。

5 个答案:

答案 0 :(得分:15)

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

locals
{
  is_tmp = "${replace(terraform.workspace, "tmp", "") != terraform.workspace}"
}

答案 1 :(得分:3)

显然对于Terraform 0.12.xx,您应该使用regexall来完成此操作。

从Terraform 0.12.XX手册中获取:

[https://www.terraform.io/docs/configuration/functions/regexall.html][1]

相关摘录: regexall也可以通过测试结果匹配列表的长度是否大于零来测试特定字符串是否匹配给定模式。

手册中的示例:

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

> length(regexall("[a-z]+", "123456789")) > 0
false

以Terraform 0.12.xx语法应用于您的案例的示例应类似于:

locals
{
  is_tmp = length(regexall(".*tmp.*", terraform.workspace)) > 0
}

在手册中还特别指出不要使用“ regex”,而应使用regexall。

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

如上所述,这是因为当您在运行计划时已发布的0.12.xx的更高版本中尝试使用该错误时,实际上会遇到异常错误。这就是我发现问题的原因,也是为什么我在这里将新答案发布回去的原因。

答案 2 :(得分:1)

如代码段中所述,使用replace( string, search, replace )

// string contains ABBA = result is ABBA
output "match" {
  value = "${ replace("xxxABBAyyy", "/(?:.*)(ABBA)(?:.*)/", "$1") }"
}
// string doesn't contain ABBA = result is original string
output "no_match" {
  value = "${ replace("xxxBABAyyy", "/(?:.*)(ABBA)(?:.*)/", "$1")}"
}
// string contains ABBA (ingorecase) = result is AbBA
output "equals_ignorecase" {
  value = "${ replace("xxxAbBAyyy", "/(?:.*)((?i)ABBA)(?:.*)/", "$1")}"
}

terraform apply的输出是:

Outputs:

equals_ignorecase = AbBA
match = ABBA
no_match = xxxBABAyyy

答案 3 :(得分:0)

在terraform 0.12.7中,我们现在有了regex。这可能有助于简化某些代码并使之可读(也许?)

> regex("[a-z]+", "53453453.345345aaabbbccc23454")
aaabbbccc

答案 4 :(得分:0)

就像@MechaStorm一样,使用Terrafor 0.12.7+,如果您的字符串包含特定的订阅,则可以使用正则表达式执行返回布尔值的操作

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

regex查询返回捕获组的列表,该捕获组包含tmp之前的任何字符,如果找到tmp,则返回tmp之后的任何字符。然后在列表中包含查找“ tmp”并返回true或false。我正在自己的Terraform中使用这种类型的登录。