How to use environment variables in Terraform

Updated: February 4, 2024 By: Guest Contributor Post a comment

This tutorial demystifies the process of using environment variables in Terraform, presenting an escalating series of examples from basic to advanced, including outputs where applicable. Mastering the art of leveraging environment variables can significantly streamline your Terraform project’s configuration, making it more dynamic and secure.

Introduction

Terraform by HashiCorp is a widely used infrastructure as code (IaC) tool that allows developers to define and provision data center infrastructure using a high-level configuration language. It is both cloud-agnostic and extensible, meaning that it supports a broad array of cloud providers and services. One of Terraform’s powerful features is its ability to incorporate environment variables into your infrastructure configuration, which can be a game-changer for managing sensitive information and setting per-environment configurations without altering your codebase.

Understanding Environment Variables

Environment variables are dynamic-named values stored within the system that can be used by applications to determine how they should operate. In Terraform, these variables can be particularly useful for storing secrets like API keys and for customizing configurations for different deployment environments (e.g., staging vs production).

Basic Usage of Environment Variables in Terraform

To begin, let’s cover how you can simply and safely introduce environment variables into your Terraform projects.

Setting Environment Variables

Environment variables intended for Terraform’s use must be prefixed with TF_VAR_, followed by the name of the variable you wish to set. For example, setting an environment variable for an AWS access key could look like this in a Unix-like shell:

export TF_VAR_access_key="your_access_key_here"

This tells Terraform to populate the variable access_key with “your_access_key_here”.

Accessing Environment Variables in Terraform

To use the variable in your Terraform code, you should define it in your variables file (usually variables.tf) like so:

variable "access_key" {}

And refer to it in your configuration:

provider "aws" {
  access_key = var.access_key
}

Intermediate Usage: Conditional Expressions and Functions

Once you’re comfortable with the basics, you can start exploring more sophisticated ways to use environment variables by integrating conditional expressions and built-in functions.

Setting Default Values

You can assign default values to variables so that your infrastructure can still be provisioned even if a particular environment variable is not set. This is a critical step in creating resilient configurations.

variable "region" {
  default = "us-west-2"
}

In this setup, if TF_VAR_region is not set, Terraform will use “us-west-2” as the default region for provisioning resources.

Using Conditional Expressions

Conditional expressions enable you to modify your configurations based on the presence or value of environment variables. For example, you might want to deploy certain resources only if operating in a production environment:

variable "env" {}

resource "aws_instance" "example" {
  count = var.env == "production" ? 1 : 0
  // Other configuration
}

This utilizes the ternary operator to conditionally create an AWS instance only when env is set to “production”.

Advanced Usage: Dynamic Blocks and Loops

At the more advanced end of the spectrum, Terraform allows complex manipulations using environment variables through dynamic blocks and loops—a feature that unlocks incredible flexibility in your configurations.

Dynamic Blocks

Dynamic blocks provide a way to dynamically construct repetitive elements of your configurations based on the content of variables.

variable "subnet_ids" {
  type = list(string)
}

resource "aws_instance" "example" {
  ami = "ami-0abc123"
  instance_type = "t2.micro"

  dynamic "network_interface" {
    for_each = var.subnet_ids
    content {
      subnet_id = network_interface.value
      device_index = index(var.subnet_ids, network_interface.value)
    }
  }
}

This dynamic block iterates over the subnet_ids list, creating a network interface for each subnet ID included in the list.

Conclusion

Mastering the use of environment variables within Terraform not only elevates the efficiency and security of your infrastructure provisioning but also introduces an unrivaled level of customization and flexibility in handling diverse deployment environments and configurations. As you become increasingly familiar with these techniques, you will find that your Terraform projects become more robust, scalable, and secure.