Encrypting sensitive variables in terraform using GnuPG agent

This post will walk you through how to encrypt sensitive terraform variables in a way that still permits them to be committed to VCS, while also being reasonably easy to decrypt. Examples use bash, however are easily adapted to other environments. Special thanks to this post on encrypting the ansible vault password, as my examples draw heavily from that source.

This method is particularly awesome, because you can explicitly declare who is permitted to decrypt it. So, for instance, all of the engineers on your team could be unable to access its contents, while your CI/CD system (jenkins or whatnot) can use their own gpg identity to decrypt the data.

Step 1: Create a json file with your sensitive variables

echo "{ \"github_api_key\": \"secret\" }" >> variables.json

Step 2: Encrypt it using gpg

gpg --encrypt ./variables.json 

The above call will ask you to add a list of recipients. In general it’s a good idea to add yourself, so you can decrypt the file at a later point. You can also add other users, such as the aforementioned CI/CD engine, or specific members of your team that you trust.

Step 3: Create an external provider in terraform

Terraform permits you to read data from external programs, as long as they return JSON. This is easily done:

data "external" "gpg" {
  program  = [ "gpg", "--batch", "--use-agent", "--decrypt", "./variables.json.gpg"]

provider "github" {
  token    = "${data.external.gpg.result.github_api_key}"

Now, assuming that you have a running gpg-agent, you’ll only have to enter your gpg passkey as your own security policy requires.

The only major caveat with the above, is that you cannot use these variables to maintain the terraform state.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.