Terraform – FotD – transpose()

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

What is it?

Function name: transpose(map)

Returns: Takes a map with lists of strings as the values. Each unique string in the lists is turned into a key. Each key has a list of strings as a value. The list of strings are any keys where the string was present in the original map. Returns a map with lists of strings as values. That is confusing, and I acknowledge it. See below in the examples for some clarification.

Example:

# Returns {Blue = [Green Purple], Red = [Orange Purple], Yellow = [Green Orange]}
output "transpose_output" {
  value = "${transpose(map("Purple",list("Red","Blue"),"Orange",list("Yellow","Red"),"Green",list("Yellow","Blue")))}"
}

Example file:

##############################################
# Function: transpose
##############################################
##############################################
# Variables
##############################################
variable "map_value" {
  type = "map"

  default = {
    "app_servers"       = ["Ford","Arthur","Zaphod"]
    "db_servers"   = ["Marvin","Trillian"]
    "web_servers" = ["Ford","Marvin"]
  }
}

variable "empty_map" {
  type = "map"

  default = {}
}

variable "second_map" {
  type = "map"

  default = {
    "four" = [1,2,4]
    "six" = [1,2,3,6]
    "eight" = [1,2,4,8]
    "ten" = [1,2,5,10]
  }
}

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

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

output "1_map_value_output" {
  value = "${transpose(var.map_value)}"
}

output "2_map_function_output" {
  value = "${transpose(map("Purple",list("Red","Blue"),"Orange",list("Yellow","Red"),"Green",list("Yellow","Blue")))}"
}

output "3_second_map_value_output" {
  value = "${transpose(var.second_map)}"
}

output "4_empty_map" {
  value = "${transpose(var.empty_map)}"
}

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

#All examples are in variables
terraform apply

Why use it?

I struggled with this one initially, and then I started to see how this could be useful with tags or groupings. The example I used above with the various types of servers shows how if I wanted to know what roles a particular server had, I could transpose the map of roles to servers. Now I know that Marvin is both a web server and a DB server. That’s a simple example, but I imagine there are lots of times where flipping the grouping could be helpful.

Lessons Learned

At first I was so confused by the documentation, I thought that the function was totally useless. It wasn’t till I tried to actually use it that things clicked. The map has to have a list type as values. It’s also okay with an empty map, since there’s nothing to do. I thought this function would just swap the keys and values in a map, but it doesn’t do that. If you were looking to take a map of keys and values that are just strings, then you could use the keys and values functions and then zipmap to put them back together in a transposed way. This transpose function is more subtle that that.

Coming up next is the trimspace() function.

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.