Terraform: How to read YAML data and convert it into a map

Updated: February 3, 2024 By: Guest Contributor Post a comment

Introduction

Terraform has become the go-to tool for building, changing, and versioning infrastructure safely and efficiently. One of the powerful features Terraform offers is its ability to integrate with various data formats, including YAML. YAML, a human-friendly data serialization standard, is widely used for configuring files. This tutorial will guide you through reading YAML data and converting it into a map in Terraform, enhancing your infrastructure as code setups.

Prerequisites

  • Basic understanding of YAML and Terraform.
  • Terraform installed on your machine.
  • A YAML file with data to be used.

Basic YAML to Map Conversion

To start with the basics, let’s create a simple YAML file named config.yaml that contains some configuration data:

regions:
  us-east-1: Virginia
  us-west-2: Oregon
environment: production

In Terraform, to read this YAML file and convert it into a map, you can use the yamldecode function along with the file function to load the file. Here’s how:

locals {
  config = yamldecode(file("${path.module}/config.yaml"))
}

This piece of Terraform code reads the config.yaml file, decodes the YAML content into a Terraform map, and stores it in a local variable called config. You can then access the values like so:

output "regions" {
  value = local.config["regions"]
}

output "environment" {
  value = local.config["environment"]
}

Advanced YAML Parsing

As we delve deeper, you may encounter more complex YAML files that contain nested structures or lists. Suppose you have the following YAML file:

users:
  - name: John
    role: Admin
  - name: Jane
    role: User

To handle such complex structures, you’ll need to parse the YAML file into a more structured Terraform map. Here’s an approach:

locals {
  users = [for user in yamldecode(file("${path.module}/users.yaml"))["users"]: {
    name = user.name
    role = user.role
  }]
}

This Terraform code iterates over the “users” list in the YAML file, creating a new list of maps with keys name and role for each user. This way, you can easily manage and access complex nested data structures.

Using YAML Maps in Terraform Modules

For larger or more distributed configurations, you may want to leverage Terraform modules. Passing YAML data into a module requires first converting the YAML into a map, and then passing it as a module parameter. Consider a scenario where you’re using a module to create resources based on the configuration defined in a YAML file:

module "resource_creator" {
  source = "./modules/resource_creator"

  config = local.config
}

This approach ensures that your modules are highly customizable and can adapt to different configurations stored in YAML files.

Dynamic Blocks Based on YAML Data

Dynamic blocks in Terraform allow creating multiple blocks of the same type from a map or a list. Suppose you want to dynamically create resources based on the YAML configuration data. For example, creating AWS security group rules based on a YAML list:

resource "aws_security_group" "example" {
  ...

  dynamic "ingress" {
    for_each = local.config["ingress_rules"]

    content {
      from_port   = ingress.value["from_port"]
      to_port     = ingress.value["to_port"]
      protocol    = ingress.value["protocol"]
      cidr_blocks = ingress.value["cidr_blocks"]
    }
  }
}

In this example, ingress_rules would be defined in a YAML file and decoded into a map in Terraform, allowing the creation of multiple ingress blocks dynamically, based on the data provided.

Conclusion

Reading YAML data and converting it into a map in Terraform allows for more dynamic and configurable infrastructure setups. By mastering these techniques, you can easily manage complex configurations and make your infrastructure as code implementations more flexible and powerful.