Skip to main content

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:

  1. String: Text values enclosed in quotes ("hello")
  2. Number: Numeric values (5, 3.14)
  3. Boolean: true or false
  4. List/Tuple: Ordered collections of values (["a", "b", "c"])
  5. Map/Object: Collections of key-value pairs ({ name = "value" })
  6. Null: The absence of a value (null)

String Conversion Functions

tostring

The tostring function converts its argument to a string value.

hcl
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

hcl
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.

hcl
locals {
string_value = "42"
number_result = tonumber(local.string_value) # 42
}

Practical Example: Calculating Capacity

hcl
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.

hcl
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

hcl
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.

hcl
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.

hcl
locals {
list_with_duplicates = ["a", "b", "a", "c", "b"]
set_result = toset(local.list_with_duplicates) # ["a", "b", "c"]
}

Practical Example: Processing Unique Tags

hcl
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.

hcl
locals {
object_value = {
name = "example"
id = 42
}

map_result = tomap(local.object_value) # { name = "example", id = 42 }
}

Practical Example: Working with Variable Inputs

hcl
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.

hcl
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

hcl
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.

hcl
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.

hcl
locals {
value = "not a number"
can_convert = can(tonumber(local.value)) # false
}

Practical Example: Defensive Programming

hcl
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:

hcl
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

  1. Validate Before Converting: Use can() to check if a conversion is possible.
  2. Provide Defaults: Use try() to handle potential conversion errors.
  3. Convert Early: Convert inputs to the appropriate type early in your configuration.
  4. Document Expectations: Add comments or variable validations to clarify expected types.
  5. 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:

hcl
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

hcl
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

hcl
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, and tobool for basic type conversions
  • Use tolist, toset, and tomap for collection type conversions
  • Employ try() and can() 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

  1. Create a Terraform configuration that accepts a comma-separated string of instance types and converts it to a list.
  2. Write a local value that safely converts a user-provided variable to a number, with validation.
  3. Create a function that takes a list of string values representing booleans and converts them to actual boolean values.
  4. Parse a JSON string containing configuration values and use them in a resource definition.
  5. 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! :)