Store Terraform secrets in YAML files with yamldecode

In May of 2019 Hashicorp released Terraform 0.12. This release completely changed the way in which variable interpolation was performed and whilst some backwards compatibility was kept, there were some breaking changes. Most notably, the way in which functions and interpolations were called with no more "${}" required.

Here's the problem statement. I want to use Terraform to create VMs on Digitalocean using the token that doctl stores in ~/.config/doctl/config.yaml. Using that same logic it made sense, to me at least, to store other variables for Cloudflare in a similar way. No tokens or other sensitive secrets in clear text Terraform code was my goal. This is how I achieved it.

I try to open up as much of infrastructure code as possible and solutions like this one enable me to do that on Github.

yamldecode()

yamldecode parses a string as a subset of YAML, and produces a representation of its value. The documentation contains some examples of YAML objects which were simple enough, but not how I was storing my data. How do you read YAML from a file?

yamldecode(file("~/.config/doctl/config.yaml"))["access-token"]

Here is the source file.

This file is hundreds of lines long but yamldecode lets us pick out the value we want using the key from the key / value pair that defines YAML data structures.

To read in the entire file simple omit the ["key"] field from the end of the yamldecode section.

Here's another example for you.

resource "cloudflare_record" "unifitest" {
  zone_id = yamldecode(file("~/.config/tokens/cloudflare.yaml"))["domain-cloud"]
  name  = "unifitest"
  type  = "A"
  ttl   = 300
  value = digitalocean_droplet.cloud.ipv4_address
}

Here we are looking up the zone_id value from cloudflare.yaml which is a file I created.

In time I will write a small installation script for these files and use Ansible Vault to store the encrypted values in Git alongside the code and then installs them to the correct paths.