Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

terraform

How do you check if a terraform string contains another string?

For example, I want to treat terraform workspaces with "tmp" in the name specially (e.g. allowing rds instances to be deleted without a snapshot), so something like this:

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

As far as I can tell, the substr interpolation function doesn't accomplish this.

like image 913
JDiMatteo Avatar asked Nov 11 '17 22:11

JDiMatteo


People also ask

How do you check if there is a substring in a string?

You can use contains(), indexOf() and lastIndexOf() method to check if one String contains another String in Java or not. If a String contains another String then it's known as a substring. The indexOf() method accepts a String and returns the starting position of the string if it exists, otherwise, it will return -1.

What is string interpolation in Terraform?

Embedded within strings in Terraform, whether you're using the Terraform syntax or JSON syntax, you can interpolate other values. These interpolations are wrapped in ${} , such as ${var. foo} . The interpolation syntax is powerful and allows you to reference variables, attributes of resources, call functions, etc.

What does EOT mean in Terraform?

EOT in this case stands for "end of text".


3 Answers

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.

like image 117
Isaac Egglestone Avatar answered Oct 20 '22 04:10

Isaac Egglestone


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

locals
{
  is_tmp = "${replace(terraform.workspace, "tmp", "") != terraform.workspace}"
}
like image 36
JDiMatteo Avatar answered Oct 20 '22 05:10

JDiMatteo


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.

like image 25
Scott Heath Avatar answered Oct 20 '22 06:10

Scott Heath