slide

Terraform fot d contains()

Ned Bellavance
3 min read

Cover

This is part of an ongoing series of posts documenting the built-in interpolation functions in Terraform. For more information, check out the beginning post. In this post I am going to cover the contains() function. The example file is on GitHub here.

What is it?

Function name: contains(list, element)

Returns: Takes a list and an element and tests if the element is in the list. Returns true if the element is present, false if it is not.

Example:

variable "list" {
  default = ["My","list","of","stuff"]
}

# Returns true
output "compact_list" {
  value = "${compact(var.list, "list")}"
}

Example file:

##############################################
# Function: contains
##############################################
##############################################
# Variables
##############################################
variable "string_list" {
  default = ["So", "long", "and", "thanks"]
}

variable "string_duplicates" {
  default = [42, 42, 42]
}

variable "empty_list" {
  default = []
}

variable "empty_string_list" {
  default = ["", "", ""]
}

variable "bool_list" {
  default = [false, true]
}

variable "nested_list" {
  default = [["one"], ["two"]]
}

##############################################
# Resources
##############################################

##############################################
# Outputs
##############################################

#Test a standard list
output "1_contains_list" {
  value = "${contains(var.string_list,"So")}"
}

#Test a standard list to false
output "2_contains_list_false" {
  value = "${contains(var.string_list,"fish")}"
}

#Test case sensitivity
output "3_string_list_case" {
  value = "${contains(var.string_list,"so")}"
}

#Test duplicates
output "4_string_list_duplicate" {
  value = "${contains(var.string_duplicates,42)}"
}

#Test what it will do with an empty list
output "5_contains_empty_list" {
  value = "${contains(var.empty_list,"")}"
}

#Test what will happen with a list full of empty strings
output "6_contains_empty_string_list" {
  value = "${contains(var.empty_string_list,"")}"
}

#Test how the function interprets boolean values
output "7_contains_bool_list" {
  value = "${contains(var.bool_list, true)}"
}

output "8_contains_bool_list_2" {
  value = "${contains(var.bool_list, 1)}"
}

output "9_contains_nested_list" {
  value = "${contains(var.nested_list,"one")}"
}

Run the following from the contains folder to get example output for a number of different cases:

#All examples are in variables
terraform apply

Why use it?

This seems like a pretty fundamental conditional test. If the element is present, like a firewall rule, don’t create a new firewall rule. I’m sure there are a ton of other examples.

Lessons Learned

The function will accept nested or flat lists, but if you try to pass it a list as the element value, then it throws an error. So although you can pass a nested list, you cannot test for the presence of a specific list in the nested list. It will always return false. I also learned that boolean values in the original list get converted to 0 and 1, so if you test for boolean true or false, it will return false since it only has 0s and 1s in the processed list. An empty list will always return false as well. The function is case sensitive, so fish and Fish are not the same thing. Duplicate values don’t seem to effect the function. If a value is present, then it is returns true, regardless of how many times that element appears.

Coming up next is the dirname() function.