How to check if string contains a substring in terraform interpolation?

Length of the list produced by split function is greater than one when separtor is a substring.

locals {
  is_tmp = length(split("tmp", terraform.workspace)) > 1
}

Like @MechaStorm, with Terrafor 0.12.7+ you can use regex to return a Boolean value if your string contains a particular substring

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

The regex query returns a list of capture groups for any characters before tmp, tmp if found, any characters after tmp. Then contains looks for "tmp" in the list and returns true or false. I am using this type of logic in my own terraform.


For terraform 0.12.xx apparently you are suppose to use regexall to do this.

From the manual for terraform 0.12.XX: regexall() documentation

regexall can also be used to test whether a particular string matches a given pattern, by testing whether the length of the resulting list of matches is greater than zero.

Example from the manual:

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

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

Example applied to your case in terraform 0.12.xx syntax should be something like:

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

It also specifically says in the manual not to use "regex" but instead use regexall.

If the given pattern does not match at all, the regex raises an error. To test whether a given pattern matches a string, use regexall and test that the result has length greater than zero.

As stated above this is because you will actually get an exception error when you try to use it in the later versions of 0.12.xx that are out now when you run plan. This is how I found this out and why I posted the new answer back here.


You can indirectly check for substrings using replace, e.g.

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

Tags:

Terraform