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.