Terraform 如何在地形插值中检查字符串是否包含子字符串?
如何检查地形字符串是否包含其他字符串 例如,我想特别对待名称中带有“tmp”的terraform工作区(例如,允许在不使用快照的情况下删除rds实例),例如:Terraform 如何在地形插值中检查字符串是否包含子字符串?,terraform,Terraform,如何检查地形字符串是否包含其他字符串 例如,我想特别对待名称中带有“tmp”的terraform工作区(例如,允许在不使用快照的情况下删除rds实例),例如: locals { is_tmp = "${"tmp" in terraform.workspace}" } 据我所知,无法完成此操作。您可以使用间接检查子字符串,例如 在代码段中使用: // string contains ABBA = result is ABBA output "match" { value = "${ re
locals
{
is_tmp = "${"tmp" in terraform.workspace}"
}
据我所知,无法完成此操作。您可以使用间接检查子字符串,例如 在代码段中使用:
// 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
在地形0.12.7中,我们现在有了。这可能有助于简化某些代码,并使其对某些人(可能?)可读
与@mechastrm类似,在Terrafor 0.12.7+中,如果字符串包含特定子字符串,则可以使用正则表达式返回布尔值
locals {
is_tmp = contains(regex("^(?:.*(tmp))?.*$",terraform.workspace),"tmp")
}
正则表达式查询返回tmp之前任何字符、tmp(如果找到)和tmp之后任何字符的捕获组列表。然后包含在列表中查找“tmp”,并返回true或false。我在我自己的terraform中使用这种类型的逻辑。对于terraform 0.12.xx,显然您应该使用regexall来实现这一点 从terraform 0.12.XX的手册中: 相关摘录: 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的更高版本中使用它时,您实际上会得到一个异常错误,该版本在您运行plan时已过时。这就是我发现这一点的原因,也是我在这里发布新答案的原因。我希望这不是最好的答案。另外,据我所知,我不能定义一个terraform
contains
函数(我想我可以定义一个contains
terraform模块来实现这一点,但是模块实例化将比仅仅复制这个逻辑更为详细)。非常遗憾的是contains
函数只能与列表一起工作。。我有包含分隔符的字符串,因此我可以使用split
测试。。。但如果将来我们更换分离器或其他东西,它就会破裂…:(例如,使用@VincentDeSmetenabled=“${contains(split(“.”,var.instance_type),“t2”)?false:true}”
如果找不到匹配项,则会引发错误。最好使用regexall()
withlength(regexall())>0
检查以保持优雅。这里@isaaceglestone共享的示例
> length(regexall("[a-z]+", "1234abcd5678efgh9"))
2
> length(regexall("[a-z]+", "123456789")) > 0
false
locals
{
is_tmp = length(regexall(".*tmp.*", terraform.workspace)) > 0
}