27 Powerful Built-in Terraform Functions to Enhance Your Workflow
Panchanan Panigrahi
Posted on September 28, 2024
- What are Terraform Functions?
- 1. toset Function
- 2. format Function
- 3. formatlist Function
- 4. join Function
- 5. split Function
- 6. length Function
- 7. lookup Function
- 8. merge Function
- 9. concat Function
- 10. flatten Function
- 11. slice Function
- 12. zipmap Function
- 13. Working with key and value in Maps
- 14. element Function
- 15. index Function
- 16. contains Function
- 17. distinct Function
- 18. coalesce Function
- 19. coalescelist Function
- 20. one Function
- 21. try Function
- 22. can Function
- 23. file Function
- 24. templatefile Function
- 25. Base64 Functions: base64encode and base64decode
- 26. JSON Functions: jsonencode and jsondecode
- 27. YAML Functions: yamlencode and yamldecode
- Final Thoughts
Terraform is a powerful Infrastructure as Code (IaC) tool packed with built-in functions that enhance your workflow. These functions are game-changers for managing and automating infrastructure.
In this blog, we’ll explore 27 essential built-in functions every Terraform user should know. Whether you're a beginner or looking to refine your skills, this guide will help you write efficient, maintainable, and scalable code. Let’s discover how these functions can elevate your Terraform journey!
What are Terraform Functions?
Terraform functions are versatile tools for data manipulation and transformation in your configurations. They allow for operations like string formatting, arithmetic calculations, and managing lists and maps.
By using these functions, you can create dynamic and maintainable infrastructure code that adheres to the DRY (Don’t Repeat Yourself) principle, simplifying the provisioning and management of your resources.
1. toset Function
The toset
function is used to convert a list or tuple into a set. This transformation helps eliminate duplicate values, ensuring that each element in the set is unique.
Syntax:
toset(list)
Example:
variable "my_list" {
default = ["apple", "banana", "apple", "orange"]
}
output "unique_fruits" {
value = toset(var.my_list)
}
In this example, the toset
function converts the list ["apple", "banana", "apple", "orange"]
into a set, resulting in {"apple", "banana", "orange"}
by removing the duplicate "apple." This is particularly useful when you want to ensure unique values in your configurations.
2. format Function
The format
function allows you to create a formatted string by embedding variable values into a predefined format string. It offers flexibility in handling various data types like strings, integers, and floats, making it a versatile tool for generating dynamic content.
Syntax:
format(format_string, arg1, arg2, ...)
-
format_string
: The main string containing placeholders (e.g.,%s
,%d
,%.2f
) that specify how the variable values should be formatted. -
arg1, arg2, ...
: Values to be substituted in the placeholders.
Supported Placeholders:
-
%s
– For strings -
%d
– For integers -
%f
– For floating-point numbers -
%t
– For boolean values -
%v
– For automatic formatting (default representation of the value) -
%#v
– For a Go-syntax representation of the value (useful for complex data structures)
Examples:
1. Formatting Strings
variable "first_name" {
default = "John"
}
variable "last_name" {
default = "Doe"
}
output "formatted_name" {
value = format("Full Name: %s %s", var.first_name, var.last_name)
}
Output: "Full Name: John Doe"
2. Formatting Integers
variable "age" {
default = 30
}
output "formatted_age" {
value = format("Age: %d years", var.age)
}
Output: "Age: 30 years"
3. Formatting Floats
variable "price" {
default = 25.6789
}
output "formatted_price" {
value = format("Total Price: %.2f USD", var.price)
}
Output: "Total Price: 25.68 USD"
-
%.2f
specifies that the float should be formatted with 2 decimal places.
4. Boolean Values
variable "is_active" {
default = true
}
output "status_message" {
value = format("Status: %t", var.is_active)
}
Output: "Status: true"
5. Using Automatic Formatting with %v
variable "items" {
default = [1, "apple", 3.14, true]
}
output "mixed_output" {
value = format("Values: %v", var.items)
}
Output: "Values: [1 apple 3.14 true]"
3. formatlist Function
The formatlist
function formats a list of values using a specified pattern. It’s perfect for situations where you need to apply consistent formatting to multiple elements.
Syntax:
formatlist(format_string, values...)
-
format_string
: The format pattern to apply to each value in the list. -
values...
: The list of values to format.
Supported Placeholders:
The placeholders in formatlist
work the same way as those in the format
function, allowing you to handle strings, integers, floats, and booleans.
Examples:
1. Formatting a List of Strings
variable "cities" {
default = ["New York", "Los Angeles", "Chicago"]
}
output "city_greetings" {
value = formatlist("Welcome to %s!", var.cities)
}
Output: ["Welcome to New York!", "Welcome to Los Angeles!", "Welcome to Chicago!"]
2. Formatting a List of Integers
variable "scores" {
default = [95, 85, 75]
}
output "formatted_scores" {
value = formatlist("Score: %d", var.scores)
}
Output: ["Score: 95", "Score: 85", "Score: 75"]
3. Formatting a List of Floats
variable "percentages" {
default = [0.875, 0.923, 0.658]
}
output "formatted_percentages" {
value = formatlist("Percentage: %.1f%%", var.percentages)
}
Output: ["Percentage: 87.5%", "Percentage: 92.3%", "Percentage: 65.8%"]
- The
%.1f%%
format specifies one decimal place and includes the percentage symbol.
4. Using Automatic Formatting with %v
in Lists
variable "mixed_values" {
default = [42, "banana", true]
}
output "formatted_list" {
value = formatlist("Value: %v", var.mixed_values)
}
Output: ["Value: 42", "Value: banana", "Value: true"]
4. join Function
The join
function in Terraform is used to concatenate elements of a list into a single string, using a specified delimiter. This is especially useful when you need to combine multiple values into a single formatted string.
Syntax:
join(delimiter, list)
-
delimiter
: The string that separates each element in the list when joined. -
list
: The list of values to be concatenated into a single string.
Examples:
1. Joining a List of Strings
variable "languages" {
default = ["Go", "Python", "Java"]
}
output "joined_languages" {
value = join(", ", var.languages)
}
Output: "Go, Python, Java"
- The
join
function combines the list into a single string, using", "
as the separator.
2. Joining with No Delimiter
variable "letters" {
default = ["a", "b", "c"]
}
output "combined_letters" {
value = join("", var.letters)
}
Output: "abc"
- The
join
function combines all elements with no space between them.
3. Joining Integers (Converted to Strings)
Although join
directly works with strings, you can convert integers to strings before joining them:
variable "numbers" {
default = ["1", "2", "3"]
}
output "joined_numbers" {
value = join("-", var.numbers)
}
Output: "1-2-3"
- This example demonstrates that if numbers are already strings, you can join them seamlessly using
"-"
as a delimiter.
5. split Function
The split
function does the opposite of join
. It splits a string into a list of substrings based on a specified delimiter, making it useful when you need to break down complex strings into individual components.
Syntax:
split(delimiter, string)
-
delimiter
: The string used to split the main string. -
string
: The original string to be split into a list.
Examples:
1. Splitting a Comma-Separated String
variable "comma_separated" {
default = "apple,orange,banana"
}
output "fruits_list" {
value = split(",", var.comma_separated)
}
Output: ["apple", "orange", "banana"]
- The
split
function converts the comma-separated string into a list of fruits.
2. Splitting a String with Spaces
variable "sentence" {
default = "Terraform makes infrastructure simple"
}
output "words_list" {
value = split(" ", var.sentence)
}
Output: ["Terraform", "makes", "infrastructure", "simple"]
- Here, the
split
function breaks the sentence into individual words using a space as the delimiter.
3. Splitting with a Complex Delimiter
variable "complex_string" {
default = "one#two#three#four"
}
output "split_result" {
value = split("#", var.complex_string)
}
Output: ["one", "two", "three", "four"]
- The
split
function uses"#"
to separate the elements.
4. Splitting a String and Joining Again
You can combine split
and join
for more complex manipulations:
variable "data" {
default = "cat,dog,bird"
}
output "modified_animals" {
value = join(" | ", split(",", var.data))
}
Output: "cat | dog | bird"
- This example demonstrates splitting a comma-separated string into a list, then joining it back with
" | "
as the new delimiter.
6. length Function
The length
function is used to determine the number of elements in a collection, such as a list, map, or string. It's quite handy for validation, conditionals, or loops within your Terraform configurations.
Syntax:
length(collection)
-
collection
: Can be a list, map, or string.
Examples:
1. Finding the Length of a List
variable "colors" {
default = ["red", "green", "blue"]
}
output "colors_count" {
value = length(var.colors)
}
Output: 3
- The
length
function counts the number of elements in the listcolors
.
2. Determining the Length of a Map
variable "person" {
default = {
name = "Alice"
age = 30
gender = "female"
}
}
output "person_attributes" {
value = length(var.person)
}
Output: 3
- The
length
function counts the number of key-value pairs in the mapperson
.
3. Calculating the Length of a String
variable "welcome_message" {
default = "Hello, Terraform!"
}
output "message_length" {
value = length(var.welcome_message)
}
Output: 16
- The
length
function returns the total number of characters in the string, including spaces and punctuation.
7. lookup Function
The lookup
function is used to retrieve a value from a map based on a given key, with an optional default value if the key is not found. This function is beneficial for handling dynamic values or defaults in your configurations.
Syntax:
lookup(map, key, default)
-
map
: The map from which to retrieve the value. -
key
: The key to look up. -
default
: (Optional) The value to return if the key doesn't exist.
Examples:
1. Retrieving a Value from a Map
variable "region_settings" {
default = {
us-east-1 = "Virginia"
us-west-1 = "California"
}
}
output "selected_region" {
value = lookup(var.region_settings, "us-east-1", "Unknown")
}
Output: "Virginia"
- The
lookup
function retrieves the value for the key"us-east-1"
from the mapregion_settings
.
2. Using a Default Value When the Key Is Missing
output "undefined_region" {
value = lookup(var.region_settings, "eu-central-1", "Unknown")
}
Output: "Unknown"
- Since
"eu-central-1"
does not exist in the map, thelookup
function returns the default value"Unknown"
.
3. Nested lookup
Example
variable "settings" {
default = {
database = {
host = "db.example.com"
port = 5432
}
}
}
output "database_host" {
value = lookup(var.settings["database"], "host", "localhost")
}
Output: "db.example.com"
- The
lookup
function accesses nested map values efficiently.
8. merge Function
The merge
function combines two or more maps into a single map. This function is useful when you need to consolidate configurations from multiple sources or override default values with specific ones.
Syntax:
merge(map1, map2, ...)
-
map1, map2, ...
: Two or more maps to be merged into a single map.
Examples:
1. Merging Two Maps
variable "default_config" {
default = {
environment = "dev"
instance_type = "t2.micro"
}
}
variable "override_config" {
default = {
instance_type = "t3.small"
region = "us-west-2"
}
}
output "final_config" {
value = merge(var.default_config, var.override_config)
}
Output: {
environment = "dev"
instance_type = "t3.small"
region = "us-west-2"
}
- The
merge
function combinesdefault_config
andoverride_config
, withoverride_config
taking precedence in case of conflicting keys.
2. Merging Multiple Maps
variable "map1" {
default = {
a = 1
b = 2
}
}
variable "map2" {
default = {
b = 3
c = 4
}
}
variable "map3" {
default = {
d = 5
}
}
output "combined_map" {
value = merge(var.map1, var.map2, var.map3)
}
Output: {
a = 1
b = 3
c = 4
d = 5
}
- The
merge
function combines all three maps, with later maps (map2
andmap3
) taking precedence over earlier ones in case of overlapping keys.
3. Using merge
with Nested Maps
variable "base_settings" {
default = {
database = {
host = "db.local"
port = 3306
}
}
}
variable "additional_settings" {
default = {
database = {
user = "admin"
password = "secret"
}
}
}
output "merged_settings" {
value = merge(var.base_settings["database"], var.additional_settings["database"])
}
Output: {
host = "db.local"
port = 3306
user = "admin"
password = "secret"
}
- The
merge
function combines the nested maps under thedatabase
key, creating a more complete configuration.
9. concat Function
The concat
function combines multiple lists into a single list. It doesn’t remove duplicates and preserves the order of elements from each list.
Syntax:
concat(list1, list2, ...)
-
list1, list2, ...
: Two or more lists to be concatenated.
Examples:
1. Concatenating Two Lists
variable "list1" {
default = ["apple", "banana"]
}
variable "list2" {
default = ["cherry", "date"]
}
output "combined_list" {
value = concat(var.list1, var.list2)
}
Output: ["apple", "banana", "cherry", "date"]
- The
concat
function combineslist1
andlist2
into a single list.
2. Concatenating with an Empty List
variable "empty_list" {
default = []
}
variable "fruits" {
default = ["grape", "orange"]
}
output "result_list" {
value = concat(var.empty_list, var.fruits)
}
Output: ["grape", "orange"]
- Concatenating an empty list with another list results in just the non-empty list.
3. Concatenating Multiple Lists
variable "list_a" {
default = ["one", "two"]
}
variable "list_b" {
default = ["three"]
}
variable "list_c" {
default = ["four", "five"]
}
output "combined_multiple_lists" {
value = concat(var.list_a, var.list_b, var.list_c)
}
Output: ["one", "two", "three", "four", "five"]
- Multiple lists are combined into one ordered list.
10. flatten Function
The flatten
function is used to convert a nested list (a list of lists) into a single, flat list. It's useful for removing nested layers when you need a single-level list.
Syntax:
flatten(list)
-
list
: The nested list you want to flatten.
Examples:
1. Flattening a Simple Nested List
variable "nested_list" {
default = [["a", "b"], ["c", "d"], ["e"]]
}
output "flat_list" {
value = flatten(var.nested_list)
}
Output: ["a", "b", "c", "d", "e"]
- The
flatten
function removes the inner list structure, resulting in a single-level list.
2. Flattening Lists with Empty Lists
variable "mixed_nested_list" {
default = [["apple", "banana"], [], ["cherry"]]
}
output "flattened_result" {
value = flatten(var.mixed_nested_list)
}
Output: ["apple", "banana", "cherry"]
- Empty lists within the nested list are ignored, resulting in a flat list.
3. Flattening Multiple Levels of Nesting
variable "deep_nested_list" {
default = [[[1, 2]], [3, 4], [5]]
}
output "flat_deep_list" {
value = flatten(flatten(var.deep_nested_list))
}
Output: [1, 2, 3, 4, 5]
- Applying
flatten
multiple times can help when there are multiple levels of nesting.
11. slice Function
The slice
function extracts a sublist from a given list, using start and end index values.
Syntax:
slice(list, start, end)
-
list
: The list to slice. -
start
: The start index (inclusive). -
end
: The end index (exclusive).
Examples:
1. Slicing a List from Index 1 to 3
variable "numbers" {
default = [10, 20, 30, 40, 50]
}
output "sliced_list" {
value = slice(var.numbers, 1, 3)
}
Output: [20, 30]
- The
slice
function extracts elements from index1
to3
(excluding3
).
2. Slicing to the End of a List
output "slice_to_end" {
value = slice(var.numbers, 2, length(var.numbers))
}
Output: [30, 40, 50]
- Using
length(var.numbers)
as the end index slices the list up to the last element.
3. Handling Negative Indices
output "negative_slice" {
value = slice(var.numbers, -3, -1)
}
Output: [30, 40]
- Negative indices count from the end of the list.
12. zipmap Function
The zipmap
function creates a map by combining two lists: one for the keys and another for the values. It’s useful when you want to transform two related lists into a key-value structure.
Syntax:
zipmap(keys, values)
-
keys
: A list of keys. -
values
: A list of values corresponding to each key.
Examples:
1. Creating a Simple Map
variable "keys" {
default = ["name", "age", "city"]
}
variable "values" {
default = ["Alice", 30, "New York"]
}
output "person_map" {
value = zipmap(var.keys, var.values)
}
Output: {
"name" = "Alice"
"age" = 30
"city" = "New York"
}
- The
zipmap
function combineskeys
andvalues
into a map.
2. Handling Lists of Different Lengths
If the keys
list is longer than the values
list, zipmap
fills the missing values with null
.
variable "keys_extra" {
default = ["one", "two", "three", "four"]
}
variable "values_short" {
default = [1, 2]
}
output "mismatched_zipmap" {
value = zipmap(var.keys_extra, var.values_short)
}
Output: {
"one" = 1
"two" = 2
"three" = null
"four" = null
}
- The additional keys are paired with
null
values.
3. Using zipmap
with Computed Values
variable "countries" {
default = ["USA", "Canada", "Mexico"]
}
variable "codes" {
default = ["US", "CA", "MX"]
}
output "country_code_map" {
value = zipmap(var.countries, var.codes)
}
Output: {
"USA" = "US"
"Canada" = "CA"
"Mexico" = "MX"
}
- The
zipmap
function efficiently maps country names to their respective codes.
13. Working with key and value in Maps
In Terraform, you often need to work with keys and values from maps. Although there's no direct key
or value
function, you can use the keys()
and values()
functions to extract all keys or values from a map, respectively.
a. keys
Function
The keys
function retrieves all keys from a given map as a list.
Syntax:
keys(map)
-
map
: The map from which you want to extract keys.
Example:
Extracting Keys
variable "server_config" {
default = {
instance_type = "t2.micro"
region = "us-east-1"
availability = "zone-a"
}
}
output "config_keys" {
value = keys(var.server_config)
}
Output: ["instance_type", "region", "availability"]
- This returns all the keys from the
server_config
map as a list.
b. values
Function
The values
function retrieves all values from a given map as a list.
Syntax:
values(map)
-
map
: The map from which you want to extract values.
Example:
Extracting Values
output "config_values" {
value = values(var.server_config)
}
Output: ["t2.micro", "us-east-1", "zone-a"]
- This returns all the values from the
server_config
map as a list.
14. element Function
The element
function retrieves an item from a list based on its index. If the index is out of range, it wraps around using the modulo operation.
Syntax:
element(list, index)
-
list
: The list from which you want to retrieve an element. -
index
: The position of the element you want to access.
Examples:
1. Basic Element Access
variable "fruit_list" {
default = ["apple", "banana", "cherry"]
}
output "second_element" {
value = element(var.fruit_list, 1)
}
Output: "banana"
- The element at index
1
in the list is"banana"
.
2. Accessing Out-of-Bounds Index
output "wrapped_index" {
value = element(var.fruit_list, 4)
}
Output: "banana"
- Index
4
wraps around to1
(4 % 3 = 1
).
15. index Function
The index
function returns the position of a given value within a list. If the value isn't found, it throws an error.
Syntax:
index(list, value)
-
list
: The list to search. -
value
: The value you want to find.
Examples:
1. Finding the Index of a Value
variable "colors" {
default = ["red", "green", "blue"]
}
output "index_of_green" {
value = index(var.colors, "green")
}
Output: 1
-
"green"
is located at index1
.
2. Value Not Found
output "index_of_yellow" {
value = index(var.colors, "yellow")
}
Error: The index
function will throw an error because "yellow"
isn't in the list.
16. contains Function
The contains
function checks if a list contains a specific value and returns true
or false
.
Syntax:
contains(list, value)
-
list
: The list to search. -
value
: The value to check.
Examples:
1. Checking for Presence
variable "animals" {
default = ["cat", "dog", "bird"]
}
output "contains_dog" {
value = contains(var.animals, "dog")
}
Output: true
-
"dog"
is in the list, socontains
returnstrue
.
2. Value Not Present
output "contains_fish" {
value = contains(var.animals, "fish")
}
Output: false
-
"fish"
isn't in the list, resulting infalse
.
17. distinct Function
The distinct
function removes duplicate values from a list and returns a new list with only unique elements.
Syntax:
distinct(list)
-
list
: The list from which duplicates should be removed.
Examples:
1. Removing Duplicates
variable "numbers" {
default = [1, 2, 2, 3, 4, 4, 5]
}
output "unique_numbers" {
value = distinct(var.numbers)
}
Output: [1, 2, 3, 4, 5]
- The
distinct
function removes the duplicate2
and4
values.
2. Handling Lists with All Unique Elements
variable "unique_list" {
default = ["apple", "banana", "cherry"]
}
output "still_unique" {
value = distinct(var.unique_list)
}
Output: ["apple", "banana", "cherry"]
- The list remains unchanged as all elements are already unique.
Let's explore the coalesce
, coalescelist
, and one
functions in Terraform, complete with detailed explanations, syntax, and examples.
18. coalesce Function
The coalesce
function returns the first non-null value from a list of arguments. This is particularly useful for setting default values or handling optional variables.
Syntax:
coalesce(value1, value2, ...)
-
value1, value2, ...
: A list of values to evaluate. The function returns the first value that is not null.
Examples:
1. Basic Coalesce Usage
variable "var1" {
default = null
}
variable "var2" {
default = "default_value"
}
output "first_non_null" {
value = coalesce(var.var1, var.var2, "fallback_value")
}
Output: "default_value"
- The function returns
var2
because it is the first non-null value.
2. All Values Null
variable "var3" {
default = null
}
output "all_null" {
value = coalesce(var.var1, var.var3)
}
Output: null
- Since all values are null, the result is null.
19. coalescelist Function
The coalescelist
function is similar to coalesce
, but it works with lists. It returns the first non-empty list from a list of lists.
Syntax:
coalescelist(list1, list2, ...)
-
list1, list2, ...
: A list of lists to evaluate. The function returns the first non-empty list.
Examples:
1. Basic Coalescelist Usage
variable "list1" {
default = []
}
variable "list2" {
default = ["apple", "banana"]
}
output "first_non_empty_list" {
value = coalescelist(var.list1, var.list2, ["fallback"])
}
Output: ["apple", "banana"]
- The function returns
list2
as it is the first non-empty list.
2. All Lists Empty
variable "empty_list1" {
default = []
}
variable "empty_list2" {
default = []
}
output "all_empty_lists" {
value = coalescelist(var.empty_list1, var.empty_list2)
}
Output: []
- Since all lists are empty, the result is an empty list.
20. one Function
The one
function checks if exactly one of its arguments is non-null and returns that value. If none or more than one argument is non-null, it results in an error.
Syntax:
one(value1, value2, ...)
-
value1, value2, ...
: A list of values to evaluate. It checks if exactly one is non-null.
Examples:
1. Basic One Usage
variable "single_value" {
default = "only_value"
}
output "exactly_one_non_null" {
value = one(var.single_value, null)
}
Output: "only_value"
- The function returns
single_value
because it is the only non-null value.
2. More than One Non-Null
variable "var4" {
default = "value_1"
}
variable "var5" {
default = "value_2"
}
output "more_than_one_non_null" {
value = one(var.var4, var.var5)
}
Error: The function will throw an error because there are two non-null values.
3. No Non-Null Values
output "no_non_null" {
value = one(null, null)
}
Error: The function will throw an error because there are no non-null values.
21. try Function
The try
function is a powerful utility that attempts to evaluate a list of expressions in order. It returns the result of the first expression that does not produce an error. This is particularly useful for error handling and providing fallback values when working with resources or variables that may not always be available.
Syntax:
try(expression1, expression2, ...)
-
expression1, expression2, ...
: A list of expressions to evaluate in order. The function returns the result of the first expression that succeeds without error.
Examples:
1. Basic Try Usage
variable "valid_variable" {
default = "I am valid"
}
variable "invalid_variable" {
default = null
}
output "try_example" {
value = try(var.valid_variable, var.invalid_variable, "Fallback Value")
}
Output: "I am valid"
- In this case,
try
returnsvar.valid_variable
since it successfully evaluates without error.
2. Handling Errors Gracefully
output "handle_errors" {
value = try(length(var.invalid_variable), "Length calculation failed")
}
Output: "Length calculation failed"
- Here, the
length
function fails becausevar.invalid_variable
is null, sotry
returns the fallback string instead of throwing an error.
3. Multiple Expressions
variable "input_value" {
default = null
}
output "multiple_expressions" {
value = try(length(var.input_value), var.valid_variable, "Fallback Result")
}
Output: "I am valid"
-
try
first attempts to get the length ofvar.input_value
, which is null (and fails), then it evaluatesvar.valid_variable
, which succeeds.
4. All Expressions Fail
output "all_fail" {
value = try(null, null, null, "All expressions failed")
}
Output: "All expressions failed"
- Since all provided expressions fail,
try
returns the final fallback string.
22. can Function
The can
function is a useful utility in Terraform that determines whether an expression can be evaluated without causing an error. It returns a boolean value: true
if the expression can be evaluated without errors, and false
otherwise. This function is particularly helpful for conditional logic and error handling.
Syntax:
can(expression)
-
expression
: The expression you want to evaluate. If the expression can be executed without causing an error,can
returnstrue
; otherwise, it returnsfalse
.
Examples:
1. Basic Can Usage
variable "valid_input" {
default = "Hello, Terraform!"
}
output "is_valid" {
value = can(length(var.valid_input))
}
Output: true
- The
length
function successfully evaluates the valid string, socan
returnstrue
.
2. Evaluating a Null Variable
variable "null_input" {
default = null
}
output "is_null" {
value = can(length(var.null_input))
}
Output: false
- The
length
function cannot evaluate a null variable, socan
returnsfalse
.
3. Using Can in Conditional Logic
variable "optional_value" {
default = null
}
output "conditional_message" {
value = can(var.optional_value) ? "Value is present" : "Value is absent"
}
Output: "Value is absent"
- Here,
can
checks ifvar.optional_value
is valid. Since it is null, the output reflects that the value is absent.
4. Checking Function Calls
output "check_function" {
value = can(1 / 0) ? "No error" : "Error occurred"
}
Output: "Error occurred"
- Division by zero would normally cause an error, but
can
captures this and returnsfalse
, allowing the output to indicate an error occurred.
23. file Function
The file
function reads the contents of a file and returns it as a string. This function is useful for including configuration files, scripts, or other text-based resources directly into your Terraform configurations.
Syntax:
file(path)
-
path
: The relative or absolute path to the file you want to read.
Examples:
1. Basic File Usage
Assuming you have a file named example.txt
with the content Hello, Terraform!
.
output "file_content" {
value = file("example.txt")
}
Output: "Hello, Terraform!"
- The
file
function reads the contents ofexample.txt
and returns it as a string.
2. Reading a Configuration File
output "config_content" {
value = file("${path.module}/config.json")
}
Output: (Content of config.json
)
- This example reads the contents of a JSON configuration file located in the same directory as the Terraform module.
3. Error Handling
If the specified file does not exist:
output "missing_file" {
value = file("missing.txt")
}
Error: This will throw an error indicating that the file does not exist.
24. templatefile Function
The templatefile
function renders a template file using variables provided in a map. This is particularly useful for creating dynamic configurations where you need to substitute values into a template.
Syntax:
templatefile(path, vars)
-
path
: The path to the template file. -
vars
: A map of variables to substitute in the template.
Examples:
1. Basic Templatefile Usage
Assuming you have a template file named greeting.tmpl
with the following content:
Hello, ${name}!
You can use templatefile
like this:
variable "user_name" {
default = "Terraform User"
}
output "greeting" {
value = templatefile("greeting.tmpl", { name = var.user_name })
}
Output: "Hello, Terraform User!"
- The
templatefile
function substitutes the${name}
placeholder in the template with the value ofvar.user_name
.
2. Using Multiple Variables
Assuming a template file config.tmpl
:
{
"region": "${region}",
"instance_type": "${instance_type}"
}
You can render it like this:
output "config" {
value = templatefile("config.tmpl", { region = "us-east-1", instance_type = "t2.micro" })
}
Output:
{
"region": "us-east-1",
"instance_type": "t2.micro"
}
- This example substitutes multiple variables in a JSON configuration template.
3. Error Handling
If the specified template file does not exist:
output "missing_template" {
value = templatefile("missing.tmpl", { name = "User" })
}
Error: This will throw an error indicating that the template file does not exist.
25. Base64 Functions: base64encode and base64decode
Terraform provides two essential functions for handling data in base64 format: base64encode
and base64decode
. These functions are crucial for encoding sensitive information like passwords and decoding data for use in your configurations.
25a. base64encode
Function
The base64encode
function encodes a string into base64 format, making it suitable for securely handling sensitive data.
Syntax
base64encode(string)
-
Parameters:
-
string
: The string you want to encode in base64 format.
-
Examples
1. Basic Usage
output "encoded_string" {
value = base64encode("Hello, Terraform!")
}
Output:
"SGVsbG8sIFRlcmFmb3JtIQ=="
- Encodes the string
Hello, Terraform!
into base64 format.
2. Encoding Sensitive Data
variable "secret_password" {
default = "my_secret_password"
}
output "encoded_password" {
value = base64encode(var.secret_password)
}
Output:
"bXlfc2VjcmV0X3Bhc3N3b3Jk"
- Encodes the sensitive password for secure storage.
3. Encoding JSON Data
variable "json_data" {
default = "{\"key\":\"value\"}"
}
output "encoded_json" {
value = base64encode(var.json_data)
}
Output:
"eyJrZXkiOiJ2YWx1ZSJ9"
- Encodes a JSON string into base64 format.
25b. base64decode
Function
The base64decode
function decodes a base64-encoded string back to its original form, allowing you to safely retrieve sensitive data.
Syntax
base64decode(string)
-
Parameters:
-
string
: The base64-encoded string to decode.
-
Examples
1. Basic Usage
output "decoded_string" {
value = base64decode("SGVsbG8sIFRlcmFmb3JtIQ==")
}
Output:
"Hello, Terraform!"
- Decodes the base64 string back to the original text.
2. Decoding Sensitive Data
variable "encoded_password" {
default = "bXlfc2VjcmV0X3Bhc3N3b3Jk" # base64 for "my_secret_password"
}
output "decoded_password" {
value = base64decode(var.encoded_password)
}
Output:
"my_secret_password"
- Retrieves the original password from its encoded form.
3. Decoding JSON Data
variable "encoded_json" {
default = "eyJrZXkiOiJ2YWx1ZSJ9" # base64 for '{"key":"value"}'
}
output "decoded_json" {
value = base64decode(var.encoded_json)
}
Output:
{"key":"value"}
- Decodes the base64-encoded JSON data back to its original format.
26. JSON Functions: jsonencode and jsondecode
Terraform provides two powerful functions for working with JSON data: jsonencode
and jsondecode
. These functions simplify the process of converting Terraform data structures to JSON format and vice versa, making it easier to manage configuration data.
26a. jsonencode
Function
The jsonencode
function converts a Terraform data structure into its JSON representation. This is particularly useful for generating JSON-formatted outputs or passing data to APIs.
Syntax
jsonencode(value)
-
Parameters:
-
value
: The Terraform data structure (map, list, string, number, etc.) that you want to convert to JSON.
-
Examples
1. Basic Usage
variable "my_map" {
default = {
key1 = "value1"
key2 = "value2"
}
}
output "json_output" {
value = jsonencode(var.my_map)
}
Output:
{"key1":"value1","key2":"value2"}
- Converts the Terraform map into a JSON string.
2. Encoding Lists
variable "my_list" {
default = ["apple", "banana", "cherry"]
}
output "json_list" {
value = jsonencode(var.my_list)
}
Output:
["apple","banana","cherry"]
- Converts a list of fruits into a JSON array.
3. Complex Data Structures
variable "complex_data" {
default = {
name = "John Doe"
age = 30
tags = ["developer", "terraform"]
}
}
output "json_complex" {
value = jsonencode(var.complex_data)
}
Output:
{"name":"John Doe","age":30,"tags":["developer","terraform"]}
- Encodes a complex data structure with multiple types into JSON.
26b. jsondecode
Function
The jsondecode
function takes a JSON-formatted string and converts it back into a Terraform data structure. This is useful for working with JSON data from external sources, like APIs or configuration files.
Syntax
jsondecode(json)
-
Parameters:
-
json
: The JSON string that you want to decode into a Terraform data structure.
-
Examples
1. Basic Usage
variable "json_string" {
default = "{\"key\":\"value\"}"
}
output "decoded_map" {
value = jsondecode(var.json_string)
}
Output:
{
key = "value"
}
- Decodes the JSON string into a Terraform map.
2. Decoding Lists
variable "json_list" {
default = "[\"apple\", \"banana\", \"cherry\"]"
}
output "decoded_list" {
value = jsondecode(var.json_list)
}
Output:
["apple", "banana", "cherry"]
- Converts the JSON array back into a Terraform list.
3. Decoding Complex JSON
variable "json_complex" {
default = "{\"name\":\"John Doe\", \"age\":30, \"tags\":[\"developer\", \"terraform\"]}"
}
output "decoded_complex" {
value = jsondecode(var.json_complex)
}
Output:
{
name = "John Doe"
age = 30
tags = ["developer", "terraform"]
}
- Converts complex JSON data back into a Terraform map.
Here’s the combined layout for yamlencode
and yamldecode
, formatted similarly to the previous sections:
27. YAML Functions: yamlencode and yamldecode
Terraform includes two handy functions for working with YAML data: yamlencode
and yamldecode
. These functions facilitate the conversion between Terraform data structures and YAML format, making it easier to manage configurations that require YAML representation.
27a. yamlencode
Function
The yamlencode
function converts a Terraform data structure into its YAML representation. This is particularly useful when you need to generate YAML outputs for configuration files or documentation.
Syntax
yamlencode(value)
-
Parameters:
-
value
: The Terraform data structure (map, list, string, number, etc.) that you want to convert to YAML.
-
Examples
1. Basic Usage
variable "my_map" {
default = {
key1 = "value1"
key2 = "value2"
}
}
output "yaml_output" {
value = yamlencode(var.my_map)
}
Output:
key1: value1
key2: value2
- Converts the Terraform map into a YAML string.
2. Encoding Lists
variable "my_list" {
default = ["apple", "banana", "cherry"]
}
output "yaml_list" {
value = yamlencode(var.my_list)
}
Output:
- apple
- banana
- cherry
- Converts a list of fruits into a YAML sequence.
3. Complex Data Structures
variable "complex_data" {
default = {
name = "John Doe"
age = 30
tags = ["developer", "terraform"]
}
}
output "yaml_complex" {
value = yamlencode(var.complex_data)
}
Output:
age: 30
name: John Doe
tags:
- developer
- terraform
- Encodes a complex data structure with multiple types into YAML.
27b. yamldecode
Function
The yamldecode
function takes a YAML-formatted string and converts it back into a Terraform data structure. This is useful for working with YAML data from external sources, like configuration files or APIs.
Syntax
yamldecode(yaml)
-
Parameters:
-
yaml
: The YAML string that you want to decode into a Terraform data structure.
-
Examples
1. Basic Usage
variable "yaml_string" {
default = "key: value"
}
output "decoded_map" {
value = yamldecode(var.yaml_string)
}
Output:
{
key = "value"
}
- Decodes the YAML string into a Terraform map.
2. Decoding Lists
variable "yaml_list" {
default = "- apple\n- banana\n- cherry"
}
output "decoded_list" {
value = yamldecode(var.yaml_list)
}
Output:
["apple", "banana", "cherry"]
- Converts the YAML sequence back into a Terraform list.
3. Decoding Complex YAML
variable "yaml_complex" {
default = "name: John Doe\nage: 30\ntags:\n - developer\n - terraform"
}
output "decoded_complex" {
value = yamldecode(var.yaml_complex)
}
Output:
{
name = "John Doe"
age = 30
tags = ["developer", "terraform"]
}
- Converts complex YAML data back into a Terraform map.
Final Thoughts
In conclusion, mastering Terraform's built-in functions can greatly enhance your infrastructure management. These functions streamline your workflows, reduce complexity, and allow you to write cleaner and more efficient code.
From data manipulation to seamless conversions between JSON and YAML, each function empowers you to automate and manage your resources effectively. Whether you're a beginner or an experienced user, leveraging these capabilities will transform your approach to infrastructure as code.
Embrace these tools, experiment with them, and elevate your Terraform journey to new heights. Happy coding!
Posted on September 28, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.