Terraform – FotD – formatlist()

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

What is it?

Function name: formatlist(format, list, args…)

Returns: Takes a format value and a list, followed by additional arguments. The additional arguments must be either single values or a list of the same length as the original list. Returns a list with values formatted based on the format value.

Example:

variable "string_list" {
  default = ["one","two","three"]
}

variable "int_list" {
  default = [1,2,3]
}

# Returns ["one-01,"two-02","three-03"] 
output "formatlist_output" {
  value = "${formatlist("%v-%02v",var.string_list,var.int_list)}"
}

Example file:

##############################################
# Function: formatlist
##############################################
locals {
  int_list_local = "${list("1","2","3")}"
}

##############################################
# Variables
##############################################
variable "string_1" {
  default = "Beeblebrox"
}

variable "string_list" {
  default = ["Ford", "Arthur", "Trillian"]
}

variable "int_1" {
  default = 42
}

variable "int_list" {
  default = [1, 2, 3]
}

variable "float_1" {
  default = 3.14159
}

variable "float_list" {
  default = [3.14159, 1.21, 42.42]
}

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

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

output "formatlist_one_item" {
  value = "${formatlist("%v-%v",var.string_list,var.string_1)}"
}

output "formatlist_same_items" {
  value = "${formatlist("%v-%v",var.string_list,var.int_list)}"
}

output "formatlist_three_items" {
  value = "${formatlist("%v is the answer to %v times %v",var.string_list,var.int_list,var.float_list)}"
}

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

#Using defaults
terraform apply

#Try using a string instead of list
terraform apply -var "string_list='cat'"

#Try using an empty list, may crash Terraform
terraform apply -var "string_list=[]"

#Try two different size lists, will fail on a mismatch
terraform apply -var "int_list=[1,2]"

Why use it?

It’s pretty likely you’re going to have a list of values that you would like to apply some formatting to before passing it along to another resource, module, or output. Maybe you want to take all the names of load balancers you created and create a link for each one mapped to a port in another list. This function let’s you create those links and forward them along. I could also see some use cases for taking an environment name and appending it to a bunch of list values, and then adding it to a metadata tag on an object.

Lessons Learned

Okay, for starters, learning to use the Sprintf formatting is a whole blog post in and of itself. Possibly many blog posts! If you find the documentation confusing, since you are probably not a Go developer by trade, then check out my post on the format function, where I dive into a few things that were mysterious to me.

Much like the format function, Terraform will submit all the values in variables as a string which makes using int or float specific formatting a bit challenging. I also discovered that you cannot use two different size lists, which is pretty obvious, but not necessarily intuitive at first. Even more exciting, I was able to make Terraform crash by giving it an empty list to process. Second bug found! I’ll be submitting that one shortly.

Coming up next is the indent() function. Probably has something to do with YAML. Yuck.

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.