How to effectively use YAML variables in your Terraform code

TL/DR: In this post we will explore how to easily use YAML variables inside of your Terraform code. The best part? You don't need any external tools for that and everything also applies to OpenTofu. First, let's take a look at a very simple example that will create one ec2 instance. provider "aws" { region = "eu-west-1" } resource "aws_instance" "this" { instance_type = "t2.micro" ami = "ami_id" } Now let's build a very straightforward yaml configuration that will replace the hardcoded values: region: "eu-west-1" instance_type: "t2.micro" ami: "ami_id" Let's suppose we've saved this yaml configuration in the same directory where the Terraform configuration is kept, in a file called vars.yaml. To make use of this file, we will need to use it in a locals block. Terraform has a built-in file function that let's you read the contents of your files. Because this is a yaml file, we will need to actually use something to make Terraform read from it properly. Luckily there is a function available for this too, called yamldecode. The logic would be to first open the file, then decode it, then use the local variable in which we implement the logic to use the fields from inside of it. This is how this will look like: locals { yaml_vars = yamldecode(file("./vars.yaml")) } provider "aws" { region = local.yaml_vars.region } resource "aws_instance" "this" { instance_type = local.yaml_vars.instance_type ami = local.yaml_vars.ami } Pretty straightforward, right? Now, you can take this up a notch and use it in a for_each as well. Let's suppose you build this yaml file for your instances and vpcs: instances: instance1: instance_type: t2.micro ami: ami1 tags: {"env": "dev"} instance2: instance_type: t3.micro ami: ami2 tags: {"env": "dev"} instance3: instance_type: t3.micro ami: ami2 tags: {"env": "dev"} vpcs: vpc1: cidr_block: 10.0.1.0/24 vpc2: cidr_block: 10.0.2.0/24 This is how your terraform code will look like: locals { yaml_vars = yamldecode(file("./vars.yaml")) } provider "aws" { region = "eu-west-1" } resource "aws_instance" "this" { for_each = local.yaml_vars.instances instance_type = each.value.instance_type ami = each.value.ami tags = merge({ Name: each.key }, each.value.tags) } resource "aws_vpc" "this" { for_each = local.yaml_vars.vpcs cidr_block = each.value.cidr_block } Now you can quickly generate as many EC2 instances as you'd like, and as many VPCS as you'd like by easily modifying the yaml file.

Mar 21, 2025 - 16:22
 0
How to effectively use YAML variables in your Terraform code

TL/DR:

In this post we will explore how to easily use YAML variables inside of your Terraform code.

The best part? You don't need any external tools for that and everything also applies to OpenTofu.

First, let's take a look at a very simple example that will create one ec2 instance.

provider "aws" {
  region = "eu-west-1"
}

resource "aws_instance" "this" {
  instance_type = "t2.micro"
  ami           = "ami_id"
}

Now let's build a very straightforward yaml configuration that will replace the hardcoded values:

region: "eu-west-1"
instance_type: "t2.micro"
ami: "ami_id"

Let's suppose we've saved this yaml configuration in the same directory where the Terraform configuration is kept, in a file called vars.yaml.

To make use of this file, we will need to use it in a locals block. Terraform has a built-in file function that let's you read the contents of your files. Because this is a yaml file, we will need to actually use something to make Terraform read from it properly. Luckily there is a function available for this too, called yamldecode.

The logic would be to first open the file, then decode it, then use the local variable in which we implement the logic to use the fields from inside of it.

This is how this will look like:

locals {
  yaml_vars = yamldecode(file("./vars.yaml"))
}

provider "aws" {
  region = local.yaml_vars.region
}

resource "aws_instance" "this" {
  instance_type = local.yaml_vars.instance_type
  ami           = local.yaml_vars.ami
}

Pretty straightforward, right? Now, you can take this up a notch and use it in a for_each as well.

Let's suppose you build this yaml file for your instances and vpcs:

instances:
  instance1:
    instance_type: t2.micro
    ami: ami1
    tags: {"env": "dev"}
  instance2:
    instance_type: t3.micro
    ami: ami2
    tags: {"env": "dev"}
  instance3:
    instance_type: t3.micro
    ami: ami2
    tags: {"env": "dev"}

vpcs: 
  vpc1:
    cidr_block: 10.0.1.0/24
  vpc2:
    cidr_block: 10.0.2.0/24

This is how your terraform code will look like:

locals {
  yaml_vars = yamldecode(file("./vars.yaml"))
}

provider "aws" {
  region = "eu-west-1"
}

resource "aws_instance" "this" {
  for_each      = local.yaml_vars.instances
  instance_type = each.value.instance_type
  ami           = each.value.ami
  tags          = merge({
    Name: each.key
  }, each.value.tags)
}

resource "aws_vpc" "this" {
  for_each = local.yaml_vars.vpcs
  cidr_block = each.value.cidr_block
}

Now you can quickly generate as many EC2 instances as you'd like, and as many VPCS as you'd like by easily modifying the yaml file.