The functions built into and supported by HashiCorp Terraform include the yamldecode
and yamlencode
functions for working with YAML data. These functions enable seamless integration and manipulation of YAML within Terraform configurations, enhancing the flexibility and manageability of infrastructure setups. This article explains their usage, and provides some practical applications.
Decoding YAML with yamldecode
Function
The yamldecode
function in Terraform parses a YAML string and converts it into a Terraform-compatible representation. This includes converting YAML sequences to lists, maps to objects, and handling other primitive types like strings, numbers, and booleans.
The function supports a subset of YAML 1.2, effectively translating various YAML types into their corresponding Terraform language types​.
Here’s a basic usage of the decodeyaml
function:
locals {
yaml_data = yamldecode(file("config.yaml"))
}
output "parsed_yaml" {
value = local.yaml_data
}
In this example, the file
function is used to read the file named config.yaml
, and the yamldecode
function then parses the YAML contents of the file into a Terraform data structure. The parsed data is then accessible within Terraform for further use.
To look at an expanded example of how the YAML to Terraform mapping works, here’s an example YAML file and it’s mapping to configuring an Azure VM resource:
YAML File:
instance_type: Standard_B1s
image_reference:
publisher: Canonical
offer: UbuntuServer
sku: 18.04-LTS
version: latest
tags:
environment: dev
project: demo
network_interface_ids:
- /subscriptions//resourceGroups//providers/Microsoft.Network/networkInterfaces/nic1
- /subscriptions//resourceGroups//providers/Microsoft.Network/networkInterfaces/nic2
enabled: true
optional_value: null
Terraform Configuration:
locals {
config = yamldecode(file("config.yaml"))
}
resource "azurerm_virtual_machine" "example" {
name = "example-vm"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
network_interface_ids = local.config.network_interface_ids
vm_size = local.config.instance_type
storage_image_reference {
publisher = local.config.image_reference.publisher
offer = local.config.image_reference.offer
sku = local.config.image_reference.sku
version = local.config.image_reference.version
}
os_profile {
computer_name = "hostname"
admin_username = "adminuser"
admin_password = "Password1234!"
}
tags = local.config.tags
}
output "enabled" {
value = local.config.enabled
}
output "optional_value" {
value = local.config.optional_value
}
Encoding YAML with yamlencode
Function
The yamlencode
function in HashiCorp Terraform is an essential tool for converting Terraform data structures into YAML-formatted strings. This functionality is particularly useful for generating configuration files for other systems and tools that use YAML. By understanding how to effectively use yamlencode
, you can enhance the interoperability and automation of your infrastructure as code.
The basic syntax for using yamlencode
involves passing a Terraform data structure to the function and assigning the resulting YAML string to a variable or output.
Here’s a an example of using the yamlencode
function:
locals {
map_data = {
name = "example"
value = 123
}
yaml_string = yamlencode(local.map_data)
}
output "yaml_output" {
value = local.yaml_string
}
In this example, a map data structure is encoded into a YAML string, which is then output for use elsewhere.
Here’s what the YAML output from yaml_output
will look like:
name: example
value: 123
YAML to Terraform Type Mappings
It is important to understand the type mappings between YAML and Terraform when using these functions. These include converting YAML sequences to lists, maps to objects, and handling other primitive types like string, numbers, and booleans.
The type mappings are as follows:
YAML Type | Terraform Type |
---|---|
!!str |
string |
!!float |
`number |
!!int |
number |
!!bool |
bool |
!!map |
object |
!!seq |
tuple |
!!null |
null |
These mappings between YAML and Terraform ensure that various YAML data structures can be utilized effectively within Terraform configurations.
Practical Applications
The yamldecode
and yamlencode
functions in Terraform open up a range of practical applications that enhance the flexibility and manageability of infrastructure as code (IaC). These functions enable seamless integration of YAML configurations, facilitating dynamic and automated setups.
Here are some additional practical applications for using these functions.
YAML Configuration Management
One of the primary applications of Terraform yamldecode
and yamlencode
functions is to manage complex configurations. YAML files are often used to store configuration data due to their readability and structured format. Using yamldecode
, you can decode these configurations directly into Terraform variables and resources.
Here’s some configuration settings defined for a VM using a YAML file:
instance_type: Standard_B1s
image_reference:
publisher: Canonical
offer: UbuntuServer
sku: 18.04-LTS
version: latest
tags:
environment: dev
project: b59-demo
Here’s some example Terraform code that pulls this YAML in and configures an Azure VM using the settings defined in the file:
locals {
config = yamldecode(file("config.yaml"))
}
resource "azurerm_virtual_machine" "example" {
name = "example-vm"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
network_interface_ids = [azurerm_network_interface.example.id]
vm_size = local.config.instance_type
storage_image_reference {
publisher = local.config.image_reference.publisher
offer = local.config.image_reference.offer
sku = local.config.image_reference.sku
version = local.config.image_reference.version
}
os_profile {
computer_name = "hostname"
admin_username = "b59adminuser"
admin_password = "Password1234!"
}
tags = local.config.tags
}
In this example, a YAML file defines the configuration for an Azure virtual machine. The yamldecode
function reads this file and converts it into a format that Terraform can use to create the VM.
YAML Configuration Management with Array
Since YAML is a common file format and is used by many different systems, here’s another configuration management example that incorporates an Array within the YAML to configure multiple instances of a Terraform resource.
Here’s an example YAML file that contains a property that contains an Array of objects:
monitors:
- name: CPU Usage
type: cpu
threshold: 80
- name: Memory Usage
type: memory
threshold: 75
Here’s some example Terraform code that decodes this YAML and uses it to configure multiple instances of a Terraform resource:
locals {
monitor_config = yamldecode(file("monitors.yaml"))
}
resource "example_monitor" "cpu" {
name = local.monitor_config.monitors[0].name
type = local.monitor_config.monitors[0].type
threshold = local.monitor_config.monitors[0].threshold
}
resource "example_monitor" "memory" {
name = local.monitor_config.monitors[1].name
type = local.monitor_config.monitors[1].type
threshold = local.monitor_config.monitors[1].threshold
}
This Terraform code reads the YAML configuration file, then creates multiple monitoring resources based on the parsed data.
Generate Configuration Files
The Terraform yamlencode
function can be used to dynamically generate YAML configuration files for other tools and systems. This can be particularly useful for tools like Kubernetes, which require YAML configurations.
Here’s some example Terraform code that specifies the configurations for a Kubernetes (K8s) deployment:
locals {
k8s_deployment = {
apiVersion = "apps/v1"
kind = "Deployment"
metadata = {
name = "nginx-deployment"
}
spec = {
replicas = 3
selector = {
matchLabels = {
app = "nginx"
}
}
template = {
metadata = {
labels = {
app = "nginx"
}
}
spec = {
containers = [
{
name = "nginx"
image = "nginx:1.14.2"
ports = [
{
containerPort = 80
}
]
}
]
}
}
}
}
}
resource local_file "k8s_config" {
content = yamlencode(local.k8s_deployment)
filename = "${path.module}/k8s.yaml"
}
This Terraform uses the local_file
resource type to write the YAML representation of the local.k8s_deployment
object variable to a YAML file on the local file system named k8s.yaml
.
Here’s what the YAML file output from this Terraform code will look like:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
This example outputs a Kubernetes deployment configuration file that is dynamically generated using Terraform. This method can be used to generate a dynamic YAML configuration file using Terraform that is then used with other tools or systems.
Summary
The Terraform yamldecode
and yamlencode
functions offer powerful capabilities for managing and generating YAML configurations. By leveraging these functions, you can integrate Terraform with a variety of tools and systems that use YAML, streamline your configuration management, and create dynamic, reusable infrastructure as code. These practical applications demonstrate how these functions can enhance the flexibility, maintainability, and scalability of your Terraform projects.
Original Article Source: Working with YAML in Terraform using the `yamldecode` and `yamlencode` Functions by Chris Pietschmann (If you’re reading this somewhere other than Build5Nines.com, it was republished without permission.)