Terraform – FotD – sort()

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 sort() function. The example file is on GitHub here.

What is it?

Function name: sort(list)

Returns: Takes a list and returns the same list with the values sorted in lexicographical order.

Example:

# Returns [a, b, c]
output "sort_output" {
  value = "${sort(list("c","b","a"))}"
}

Example file:

##############################################
# Function: sort
##############################################
##############################################
# Variables
##############################################
variable "string_list" {
  default = ["One", "Two", "Three", "Four"]
}

variable "string_list_2" {
  default = ["b","c","a",""]
  
}

variable "int_list" {
  default = [400, 42, 41]
}

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

variable "empty_list" {
  default = []
}

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

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

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

#Test a standard list
output "1_sort_list" {
  value = "${sort(var.string_list)}"
}

output "1b_sort_list" {
  value = "${sort(var.string_list_2)}"
}

#Test a standard int list
output "2_int_list" {
  value = "${sort(var.int_list)}"
}

#Test list of empty strings
output "3_empty_string_list" {
  value = "${sort(var.empty_string_list)}"
}

#Test what will happen with a list boolean values
output "4_bool_list" {
  value = "${sort(var.bool_list)}"
}

#This will fail.  Nested lists are not supported
#output "5_messing_around" {
#  value = "${sort(list(list("l1v1","l2v2"),list("l2v1","l2v2")))}"
#}

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

#All examples are in variables
terraform apply

Why use it?

When you’re working on a list, there’s a good chance you are going to end up sorting it. This is barebones sorting though. If you need a flat list sorted in ascending lexicographical order, then this is the function for you. Anything more advanced, and you’ll need to look elsewhere. It would be really nice if this function took a second, optional argument to reverse the sort order. And maybe a number sort function as well? It could be called numsort to avoid confusion.

Lessons Learned

I did learn a few interesting things about the sort function that I thought I would share. Per the docs, the function only takes flat lists. Don’t try to use a nested list or a list with a map in it. Errors will ensue. As noted, the sorting is based on a lexicographical order, which is a fancier way of saying alphabetical. Actually, that’s a bit flippant. Lexicographical is a more generalized version of alphabetical that is meant to deal with ordering any set of characters or other combination of data types. That allows it to deal with non-alphabetical characters and Unicode. It also means that if you hand the function a list of integers, it will not sort them by value as you might expect. My example above uses 400, 42, and 43. By value it should be sorted as (42,43,400). By lexicographical order, the 400 stays first since the first character of all the values is the same, and the second character of 0 in 400 comes before 2 or 3 in the other two values. I also discovered that an empty string will be sorted as the first value. That seems like an important thing to note if you are seeing strange behavior in your configs. I recommend using compact to remove those empty strings. Sanitized data is happy data.

Coming up next is the split() function. So let’s make like a banana…

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.