Configuring Terraform Templates: Variables and Data Resources

This is the third part of the Terraform Lightning Course.

In this article, we will look at different ways to supply configuration to Terraform templates.

We need to give Terraform extra configuration because our templates should be re-usable for different environments and different settings.

We should, whenever possible, use the same template to provision both production and test environments.

The only difference between this environments is the configuration we are injecting into the template.

Let's get straight to coding.

The first and most common way to configure Terraform templates is to use variables.

The best practice to define all the variables is to create a separate file.

When we run Terraform commands, it discovers all the files with .tf extension in the current directory.

The first variable I need is the authentication token.

It's important to keep such a sensitive data outside the Terraform template itself. Most likely, you are going to store the templates in Git. You should never store secrets in plain text in your Git repositories.

To define a variable, we need to type the variable statement followed by the variable name.

Inside the variable block we should define the variable and, when applicable, the default value.

There are multiple different variables types in Terraform.

We can use a number of simple data types, like lists, numbers, maps and simple objects in addition to the string type that I am going to use.

It's a good practice to also set the description for your variable, so that it's purpose is clear.

The second variable is the environment. I will set prod as the default value.

The last variable I will define is the project name variable.

I am also renaming the file to be, to follow the conventions set in Terraform world.

Let's open the main template.

To use variables inside the template, we need to type var.variable_name.

Let me insert new variable everywhere they should be.

Now let's see what happens if I run terraform plan.

As we did not set default values for a couple of variables, Terraform will ask for them interactively. While useful sometimes, interactive input contradicts automation.

There are three other ways to set the values for variables.

The first one, excellent for setting the secrets locally, is by using environment variables.

Terraform will recognize any environment variable starting with TF_VAR_variable name and use the the value of this environment variable as a value of Terraform variable.

I will set my auth token this way.

The second way is to supply them as command line arguments, like this:

It's not much better than setting the values interactively.

The third way is to create a variables files, with values defined inside.

We can create a production-specific file called prod.tfvars and use it for our template. Contents of this file is simply the name of the variable followed by equals sign and the variable value.

To use this file, we need to supply it on the command like, like this:

Now Terraform is not asking us to provide any variables, because it discovered all of them from the environment and from the variables file.

Variables are a very important concept in Terraform and you are going to use them a lot. They will appear to be especially useful when we will learn about Terraform modules.

Another way to get configuration into the templates is to use the data resources.

Data resources are not creating anything. Instead, they fetch the data from the provider for a particular object.

Instead of creating the Packet project every time, we can pull the id of the existing one via data resource.

To define the data resource we need to type the "data" statement, followed by the resource type and resource name.

Inside the data resource block, we need to set parameters that are needed in order for Terraform to find the requested resource.

Then, we need to update our references to the project by appending the "data" word to the resource type, like this:

Not every resource has as an according data resource. You should consult the provider documentation to discover which data resources are available.

Note that I created the Packet project beforehand, that's why I am able to fetch it with the data resource. Now let me try to run Terraform plan again.

From the output we can see the project id, that Terraform pulled by using the data resource.

Everything seems to work as expected - instead of creating 3 resources we are creating just 2. We reduced the amount of hard-coded configuration in our template and we are able to re-use this template for different purposes just by tweaking the variables.

We use only one variables type today, but you can do much more advanced things with variables.

As this is an introduction course to Terraform, I did not want to overload you with too much information just yet. We use variables a bit more when we will talk about modules.

Here's the same article in video form for your convenience: