Terraform Type Conversion Functions
Introduction
When working with Terraform, you'll often need to convert values from one data type to another. Terraform's type conversion functions enable you to transform values between strings, numbers, booleans, collections, and other types. These functions are essential when you need to:
- Process user input (which often comes as strings)
- Format data for output or display
- Ensure compatibility between different resource properties
- Manipulate data structures within your configuration
In this guide, we'll explore Terraform's built-in type conversion functions with practical examples to help you understand when and how to use them.
Understanding Terraform Data Types
Before diving into conversions, let's quickly review Terraform's basic data types:
- String: Text values enclosed in quotes (
"hello"
) - Number: Numeric values (
5
,3.14
) - Boolean:
true
orfalse
- List/Tuple: Ordered collections of values (
["a", "b", "c"]
) - Map/Object: Collections of key-value pairs (
{ name = "value" }
) - Null: The absence of a value (
null
)
String Conversion Functions
tostring
The tostring
function converts its argument to a string value.
locals {
number_value = 42
boolean_value = true
string_result_1 = tostring(local.number_value) # "42"
string_result_2 = tostring(local.boolean_value) # "true"
}
Example Output:
string_result_1 = "42"
string_result_2 = "true"
Practical Example: Formatting Resource Names
resource "aws_s3_bucket" "example" {
bucket = "app-data-${tostring(var.environment_id)}"
# Converting environment_id (which might be a number) to a string
}
Number Conversion Functions
tonumber
Converts its argument to a number value.
locals {
string_value = "42"
number_result = tonumber(local.string_value) # 42
}
Practical Example: Calculating Capacity
variable "instance_count" {
type = string
default = "3"
}
resource "aws_instance" "server" {
count = tonumber(var.instance_count) * 2 # Convert to number before multiplication
# ... other configuration
}
Boolean Conversion Functions
tobool
Converts its argument to a boolean value.
locals {
string_true = "true"
string_false = "false"
number_one = 1
number_zero = 0
bool_result_1 = tobool(local.string_true) # true
bool_result_2 = tobool(local.string_false) # false
bool_result_3 = tobool(local.number_one) # true
bool_result_4 = tobool(local.number_zero) # false
}
Practical Example: Conditional Resource Creation
variable "enable_feature" {
type = string
default = "true"
}
resource "aws_lambda_function" "optional_feature" {
count = tobool(var.enable_feature) ? 1 : 0
# Only create the resource if enable_feature is true
# ... other configuration
}
List and Set Conversion Functions
tolist
Converts its argument to a list value.
locals {
set_value = toset(["a", "b", "c"])
tuple_value = ["x", "y", "z"]
list_result_1 = tolist(local.set_value) # ["a", "b", "c"]
list_result_2 = tolist(local.tuple_value) # ["x", "y", "z"]
}
toset
Converts its argument to a set value, removing duplicates.
locals {
list_with_duplicates = ["a", "b", "a", "c", "b"]
set_result = toset(local.list_with_duplicates) # ["a", "b", "c"]
}
Practical Example: Processing Unique Tags
variable "instance_tags" {
type = list(string)
default = ["web", "app", "web", "db"]
}
locals {
# Remove duplicates using toset, then convert back to list
unique_tags = tolist(toset(var.instance_tags)) # ["web", "app", "db"]
}
Map and Object Conversion Functions
tomap
Converts its argument to a map value.
locals {
object_value = {
name = "example"
id = 42
}
map_result = tomap(local.object_value) # { name = "example", id = 42 }
}
Practical Example: Working with Variable Inputs
variable "resource_tags" {
type = any
default = { env = "dev", app = "web" }
}
resource "aws_instance" "server" {
# ... other configuration
# Ensure variable is treated as a map regardless of input format
tags = tomap(var.resource_tags)
}
Complex Type Conversions
jsondecode
and jsonencode
These functions convert between Terraform values and JSON-encoded strings.
locals {
json_string = jsonencode({
name = "example"
tags = ["tag1", "tag2"]
enabled = true
})
# Result: {"name":"example","tags":["tag1","tag2"],"enabled":true}
decoded_value = jsondecode(local.json_string)
# Result is a Terraform object matching the original structure
}
Practical Example: Working with External JSON Data
data "local_file" "config" {
filename = "${path.module}/config.json"
}
locals {
config_values = jsondecode(data.local_file.config.content)
environment = local.config_values.environment
region = local.config_values.aws_region
}
Special Conversion Functions
try
While not strictly a conversion function, try
is useful when dealing with potential conversion errors.
locals {
user_input = var.port_number
# Safely attempt to convert input to number, or use default
port = try(tonumber(local.user_input), 8080)
}
can
Tests whether an expression can be evaluated without error.
locals {
value = "not a number"
can_convert = can(tonumber(local.value)) # false
}
Practical Example: Defensive Programming
variable "instance_count" {
type = string
description = "Number of instances to create"
}
locals {
# Check if instance_count can be converted to number
valid_count = can(tonumber(var.instance_count))
# Use a conditional to set the actual count value
instance_count = local.valid_count ? tonumber(var.instance_count) : 1
}
Type Checking Functions
Terraform also provides functions to check types without actually converting them:
locals {
test_value = "42"
is_string = can(tostring(local.test_value)) # true
is_number = can(tonumber(local.test_value)) # true
is_bool = can(tobool(local.test_value)) # false (as "42" can't be converted to bool)
}
Best Practices for Type Conversions
- Validate Before Converting: Use
can()
to check if a conversion is possible. - Provide Defaults: Use
try()
to handle potential conversion errors. - Convert Early: Convert inputs to the appropriate type early in your configuration.
- Document Expectations: Add comments or variable validations to clarify expected types.
- Be Careful with Booleans: Remember that only specific string values like "true"/"false" can be converted to booleans.
Error Handling in Type Conversions
When a type conversion fails, Terraform will show an error during the plan or apply phase. For example:
Error: Invalid function argument
Cannot convert "hello" to number: string must be a number value.
To prevent such errors, use try()
and can()
to handle potential conversion failures:
locals {
user_input = "hello"
safe_number = try(tonumber(local.user_input), 0) # Uses 0 if conversion fails
}
Advanced Type Conversion Patterns
Converting Between Complex Types
locals {
# Starting with a list of objects
user_list = [
{ id = "1", name = "Alice" },
{ id = "2", name = "Bob" }
]
# Convert to a map keyed by ID
user_map = {
for user in local.user_list :
user.id => user
}
# Result: {
# "1" = { id = "1", name = "Alice" }
# "2" = { id = "2", name = "Bob" }
# }
}
Working with Type Constraints
variable "ports" {
type = list(string)
default = ["80", "443", "8080"]
}
locals {
# Convert all port strings to numbers
numeric_ports = [for port in var.ports : tonumber(port)]
}
Summary
Terraform's type conversion functions are essential tools for working with different data types in your infrastructure code. They allow you to transform values between strings, numbers, booleans, and complex data structures, making your code more flexible and robust.
Key points to remember:
- Use
tostring
,tonumber
, andtobool
for basic type conversions - Use
tolist
,toset
, andtomap
for collection type conversions - Employ
try()
andcan()
for safer conversions with error handling - Convert input values early in your configuration
- Document your type expectations clearly
By mastering these type conversion functions, you'll write more resilient Terraform code that can handle various input formats and produce consistent outputs.
Practice Exercises
- Create a Terraform configuration that accepts a comma-separated string of instance types and converts it to a list.
- Write a local value that safely converts a user-provided variable to a number, with validation.
- Create a function that takes a list of string values representing booleans and converts them to actual boolean values.
- Parse a JSON string containing configuration values and use them in a resource definition.
- Convert a list of objects to a map keyed by one of the object properties.
Additional Resources
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)