How to use Terraform variable within variable

1. Terraform Variables

Variables are an important part of Terraform because they let users change settings and make them more flexible and reusable.

You can avoid hardcoding values in your Terraform configuration files by using variables. This makes your code more flexible.

In this blog post we will focus on how to use Variables within variables and what the practices you should follow in such scenarios.

Table of Content

  1. Terraform Variables
  2. Terraform Variable within Variable
  3. Best Practices

!Important- Terraform does not support variable withing variable implementation. You have to choose either of the following alternative to implement this behavior -

  1. Use lookup function to fetch variable value from another variable
  2. Using locals and variable to implement variable within variable

But first let's take a look on type of Terraform variables -

1.1 Types of Terraform Variables

There are three types of Terraform variables:

1. Input variables: These variables let users pass values into a Terraform setup, so the infrastructure can be changed without having to change the configuration.

Example -

 1#main.tf 
 2
 3provider "aws" {
 4  # Input variable - var.aws_region
 5  region = var.aws_region
 6}
 7
 8resource "aws_instance" "example" {
 9  # Input variable - var.ami_id
10  ami           = var.ami_id
11  instance_type = "t2.micro"
12  tags = {
13    Name        = "example-instance"
14    Environment = "dev"
15  }
16}

Here is the Input variable for above example -

 1# variables.tf
 2variable "aws_region" {
 3  description = "The AWS region to deploy the resources in"
 4  type        = string
 5  default     = "us-west-2"
 6}
 7
 8variable "ami_id" {
 9  description = "The Amazon Machine Image (AMI) ID to use for the instance"
10  type        = string
11  default     = "ami-0c55b159cbfafe1f0"
12}

Here is one detailed post on How to use Terraform locals?

2. Output variables: These variables are used to pull values out of the Terraform state. This makes it easy for resources or modules to access and share information.

Example-

 1#main.tf 
 2
 3resource "aws_vpc" "example" {
 4  cidr_block = "10.0.0.0/16"
 5
 6  tags = {
 7    Name = "example-vpc"
 8  }
 9}
10
11# outputs.tf
12output "vpc_id" {
13  description = "The ID of the created VPC"
14  value       = aws_vpc.example.id
15}
  • In this case, we use the main.tf file to make an AWS VPC resource.
  • We set up one output variable in the outputs.tf file: vpc_id
  • The ID of the newly formed VPC are shown in these output variables.

When Terraform applies this configuration, it will show the values of these output variables at the end of the process. This makes it easy for users to access and use this information in other tools or configurations.

Here is one detailed post on How to use Terraform output values

3. Local variables: These are used within a Terraform configuration to simplify complicated expressions or store intermediate values that can be used later.

Example -

 1#main.tf
 2
 3# local variable
 4locals {
 5  staging_env = "staging"
 6}
 7
 8# aws vpc resource
 9resource "aws_vpc" "staging-vpc" {
10  cidr_block = "10.5.0.0/16"
11
12  tags = {
13    Name = "${local.staging_env}-vpc-tag"
14  }
15}

You can read in-depth on this post How to use Terraform locals?


2. Terraform Variable within Variable

2.1 The Concept

In the [first section][1] you have seen how to create terraform variables. Let's use those concepts and explore the idea of using nested variables(variables within variables) in Terraform.

This idea(variables within variables) makes it possible to make configurations that are more dynamic and flexible, which makes it easier to handle complex infrastructures.


2.2 Use Cases

2.2.1 Use lookup function to fetch variable value from another variable

Let's take a look on one simple example which demonstrates the use of a variable within a variable:

 1# variable.tf
 2
 3# var-1 : region
 4variable "region" {
 5  description = "The AWS region where resources will be created"
 6  type        = string
 7  default     = "us-west-2"
 8}
 9
10# var-2 : instance_types
11variable "instance_types" {
12  description = "A map of instance types for different environments"
13  type        = map(string)
14  default = {
15    dev  = "t2.micro"
16    prod = "m5.large"
17  }
18}
19
20# var-3 : environment
21variable "environment" {
22  description = "The environment for the infrastructure (e.g., dev, prod)"
23  type        = string
24  default     = "dev"
25}

Let's write main.tf and use those variables which we have created inside variable.tf.

In this case, we've set up three variables:

  • region
  • instance_types
  • environment
  1. The instance_types variable is a map that links different instance types to different environments, such as testing and production.
  2. Based on the value of the environment variable, the aws_instance resource uses the lookup function to choose the right instance type.
  3. This shows how the value of one variable (var.environment) is used in the description of another variable (var.instance_types).
 1# main.tf
 2 
 3
 4resource "aws_instance" "example" {
 5  ami           = "ami-0c55b159cbfafe1f0"
 6  
 7  # Using variable value to fetch another variable
 8  instance_type = lookup(var.instance_types, var.environment)
 9  availability_zone = "${var.region}a"
10}

2.2.2 Using locals and variable to implement variable within variable

As terraform does not support variable within variable, so another alternate would be to combine locals and variables to implement variable within variable.

Here is how this implementation would work -

  1. First we will create a variable named env with default value dev in variable.tf
1# variable.tf
2
3variable "env" {
4  description = "Tags for dev environment"
5  type        = string
6  default     = "dev"
7}
  1. Second we will create main.tf file and inside the file we will create a local and use the expression ${var.env} to create a local named tag
 1# main.tf 
 2
 3locals {
 4  tags = {
 5    Name = "${var.env}"
 6  }
 7}
 8
 9resource "aws_vpc" "staging-vpc" {
10  cidr_block = "10.5.0.0/16"
11
12  tags = {
13    Name = "${local.tags}-vpc-tag"
14  }
15}

2.3 Advantages

Using variables within variables in Terraform has a number of benefits:

  1. Flexibility: It lets you make configurations that are more dynamic, which makes it easier to adapt to changes in the system.
  2. Modularity: You can make reusable parts that can be changed to fit your needs by nesting variables.
  3. Simplicity: It cuts down on duplicate code and makes the codebase cleaner and easier to manage.

3. Best Practices

When using a Terraform variable inside another Terraform variable, it's important to follow best practices to make sure your code is easy to read and maintain:

  1. Use descriptive variable names: Use variable names that explain what they are for. Give your variables names that are clear and explain what they are for.
  2. Document your variables: Include a description for each variable in your configuration to give context and show how it should be used.
  3. Validate variable values: Use the built-in validation tools in Terraform to make sure that the numbers you pass to your variables meet the criteria you want.
  4. Organize your variables: Use consistent name rules and group variables that are similar together to make your code easier to read and understand.
  5. Avoid deep nesting: Nesting factors can be helpful, but don't make structures that are too complicated and hard to understand and keep up with.

Posts in this series