Sunday, May 31, 2020

Terraform Runtime Data

Terraform and Runtime values


The other day I was asked if we could use operating system variables in Terraform like we can in Ansible?

An interesting question.  Obviously those who know Terraform will shout out and say, of course you can you just put TF_VAR_ in front of the variable in the OS and Terraform will find it.

However, that's not the same as being able to get hold of say, HOME or PWD, etc as can be done in Ansible using the lookup function;

vars:
  cwd: "{{ lookup('env', 'PWD' }}"

The above in Ansible obtains the value of the PWD operating system environment variable and stores it in an Ansible variable called cwd at runtime.

So, how on earth do I do such a thing in Terraform, rather than relying on people configuring variables up front, or using a Makefile or wrapper script?

The data sources

The data source allows you to obtain data from various sources, see https://www.terraform.io/docs/configuration/data-sources.html, of which the best data source for our requirement is the external data source.

Example


The downside is that your external data source needs to return JSON data, so you can't just run a command or echo a variable.  But you can create the relevant JSON data.  I wrote a simple use at https://bitbucket.org/stevshil/terraform/src/master/envvar/.

To explain that code directly here I took the following steps;

  1. Create a shell script that will return JSON data, this way you don't have to work out how to escape characters, etc.  In the example code we created a script called mypwd containing the following;

    #!/bin/bash
    cat <<_END_
    {
      "dir": "$PWD"
    }
    _END_

  2. Create the Terraform code (getvar.tf) to grab the printed output;

    data "external" "example" {
     program = ["bash","./mypwd"]
    }
    output "pwd" {
      value = data.external.example.result.dir
    }

You'll notice that using the external data source, and a given name (example in this instance) we call our shell script.  The bash is there just in case someone forgot to make the script executable.

The output in this case is just to show that the data was returned in an attribute called dir as you'll note in the shell script code where we output JSON data which has a key called dir that contains the value of the operating system variable called $PWD.  We could just as easily have written Python code, or have ran another shell command that outputs the data we desire.

To retrieve the value output from our script we use the normal Terraform object attribute reference, but because it is a data source we prepend the word data to the resource - data.external.example.result.dir, with the result element being part of the data source, but the dir is our JSON data key.  This reference can be used anywhere within your code when you need to use the runtime value.

Goodbye to the TF_VAR_ potential error prone values if you need to make use of attributes from the operating system.

No comments:

Post a Comment