Terraform – FotD – format()

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

What is it?

Function name: format(format, args,…)

Returns: Takes a format value and one or more arguments that are part of the format. Returns a value formatted as specified in the format value. Uses the format style from Sprintf in Golang.

Example:

variable "format" {
  default = "string"
}

# Returns 737472696e67 which is base 16 lowercase of the string
output "format_output" {
  value = "${format("%x",var.format)}"
}

Example file:

##############################################
# Function: format
##############################################
##############################################
# Variables
##############################################
variable "string_1" {
  default = "example string"
}

variable "int_1" {
  default = 42
}

variable "float_1" {
  default = 3.14159
}

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

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

output "format_string" {
  value = "${format("%q",var.string_1)}"
}

output "format_string_16byte" {
  value = "${format("%.2X",var.string_1)}"
}

#Addition forces int value type
output "format_int_base2" {
  value = "${format("%b",var.int_1 + 0)}"
}

#Addition forces float value type
output "format_float_scientific" {
  value = "${format("%E",var.float_1 + 0.0)}"
}

output "format_float_precision" {
  value = "${format("%+.3f",var.float_1 + 0.0)}"
}

output "string_int_combo" {
  value = "${format("%v-%03d",var.string_1,var.int_1 + 0)}"
}

output "format_bool" {
  value = "${format("%t",true)}"
}

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

#Using defaults
terraform apply

#Try a negative float
terraform apply -var "float_1=-3.14159"

#Try a negative int
terraform apply -var "int_1=-42"

#Try a different string
terraform apply -var "string_1=Trillian"

Why use it?

Formatting probably works best when you have multiple arguments you want to munge together and apply a little formatting to. A good example might be naming a resource, where there are specific requirements around how the name must be formatted. You may also need to manipulate floating values to lower the precision or be converted to scientific notation. I’m not sure exactly when you would need this, but there’s no doubt that it will come up eventually.

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 let me explain a couple things that were mysterious to me. The formatting language uses a percentage sign to start a formatting block. The value being formatted is the argument being passed to the format function. Unless you explicitly specify an evaluation order, it will use each argument in the order they were given. For example, something like this:

format("%s%d","string",42) 

The %s will format the first argument – string in this case – using the ‘s’ format which explicitly deals with strings. The %d will format the second argument – 42 in this case – using the ‘d’ format which formats an integer as base 10.

You can add additional formatting to each block. For instance adding a ‘+’ to %+d tells the formatter to always display a ‘+’ sign for positive values. That might be important if spacing of the value regardless of sign is consistent. There’s a ton more, but hopefully that clears up the initial haze a bit.

I also learned in the process that Terraform will submit all the values in variables as a string, unless you force an implicit conversion. The way I found to do this is to perform a math operation on the variable. By doing something like:

var.int + 0

Terraform converts the string to an int, even though the value is not altered. Resources and data sources natively return a correct data type, so this is really only useful for variables.

Coming up next is the formatlist() 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.