🐶
Terraform

Terraform Modules: Passing Variables via CLI & tfvars

By Filip on 10/05/2024

Learn how to efficiently pass variables to your Terraform modules using both the command line interface (CLI) and tfvars files for flexible and reusable infrastructure deployments.

Terraform Modules: Passing Variables via CLI & tfvars

Table of Contents

Introduction

This article explains how to pass variables to Terraform modules using five different methods: .tfvars files, command-line arguments, environment variables, defining variables within modules, and passing variables from parent to child modules. Each method is explained with examples and code snippets. The article also highlights the order of precedence Terraform uses when resolving variable values.

Step-by-Step Guide

To pass variables to Terraform modules, you have several options:

1. Using .tfvars files:

  • Create a file with a .tfvars extension (e.g., variables.tfvars).
  • Inside this file, define your variables using the format variable_name = value. For example:
region = "us-west-2"
instance_type = "t2.micro"
  • To use this file, run Terraform commands with the -var-file flag:
terraform plan -var-file=variables.tfvars

2. Passing variables directly from the command line:

  • Use the -var flag followed by the variable name and value:
terraform apply -var 'region=us-east-1' -var 'instance_type=t3.medium'

3. Using environment variables:

  • Prefix your variable names with TF_VAR_ and set them in your environment:
export TF_VAR_region="eu-central-1"
export TF_VAR_instance_type="m5.large"
terraform apply

4. Defining variables within your module:

  • In your module's .tf file, use the variable block to declare variables:
variable "region" {
  type = string
}

variable "instance_type" {
  type = string
  default = "t2.micro"
}
  • You can then reference these variables within your module using the var.<variable_name> syntax.

5. Passing variables from a parent module to a child module:

  • In your parent module, include the child module using the module block.
  • Pass variables to the child module as arguments within the module block:
module "child_module" {
  source = "./path/to/child/module"
  region = var.region
  instance_type = var.instance_type
}

Note: Terraform prioritizes variable values in the following order (highest to lowest):

  1. Command-line arguments (-var and -var-file)
  2. Environment variables (TF_VAR_)
  3. Variable definitions within the module
  4. Default values defined for variables

Remember to choose the method that best suits your needs and maintain consistency throughout your project.

Code Example

This Terraform code defines a root module and a child module "ec2" for creating an EC2 instance on AWS. It demonstrates variable passing from the root module to the child module, including the AWS region and instance type. The code also shows how to define default values for variables and use different methods for providing variable values, such as using a .tfvars file or environment variables. The child module uses the provided variables to create an EC2 instance with the specified type and tags in the defined region.

1. variables.tf (in your root module):

variable "region" {
  type = string
  description = "The AWS region to deploy resources to."
}

variable "instance_type" {
  type = string
  description = "The type of EC2 instance to create."
  default = "t2.micro"
}

2. main.tf (in your root module):

# Configure the AWS Provider
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

provider "aws" {
  region = var.region
}

# Define a module for creating an EC2 instance
module "ec2_instance" {
  source = "./modules/ec2"

  # Pass variables to the child module
  region         = var.region
  instance_type = var.instance_type
}

3. variables.tf (in modules/ec2):

variable "region" {
  type = string
  description = "The AWS region to deploy resources to."
}

variable "instance_type" {
  type = string
  description = "The type of EC2 instance to create."
}

4. main.tf (in modules/ec2):

resource "aws_instance" "example" {
  ami           = data.aws_ami.amazon_linux_2.id
  instance_type = var.instance_type

  tags = {
    Name = "Example EC2 Instance"
  }
}

data "aws_ami" "amazon_linux_2" {
  most_recent = true

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }

  owners = ["amazon"]
}

How to use:

  1. .tfvars file: Create a file named terraform.tfvars in the same directory as your root module's main.tf and add the following:
region = "us-west-2"
instance_type = "t3.medium"
  1. Command line: Run the following command to apply your configuration:
terraform apply
  1. Environment variables: Set the following environment variables:
export TF_VAR_region="us-east-1"
export TF_VAR_instance_type="t2.small"

Then run terraform apply.

This example demonstrates how to pass variables from a parent module to a child module, define default values for variables, and use different methods for providing variable values. You can adapt this example to your specific needs and use the method that best suits your workflow.

Additional Notes

General Best Practices:

  • Use descriptive variable names: Make your code self-documenting by using clear and informative names for your variables.
  • Provide clear descriptions: Use the description attribute within the variable block to explain the purpose of each variable.
  • Validate variable values: Use the validation block within the variable block to enforce constraints on variable values (e.g., string length, allowed values).
  • Use a consistent naming convention: Choose a naming convention for your variables (e.g., snake_case, camelCase) and stick to it throughout your project.
  • Don't hardcode sensitive information: Avoid storing sensitive data like passwords and API keys directly in your code. Use a secrets management solution instead.

Specific to Methods:

  • .tfvars files:
    • Useful for storing multiple variable values and reusing them across different environments.
    • Can be combined with command-line arguments for overriding specific values.
  • Command-line arguments:
    • Convenient for quick testing and overriding individual variable values.
    • Not suitable for storing sensitive information.
  • Environment variables:
    • Useful for integrating with CI/CD pipelines and other automation tools.
    • Can be less explicit than other methods, making it harder to track variable values.
  • Defining variables within modules:
    • Provides default values for variables, making modules more reusable.
    • Allows for module-specific configurations.
  • Passing variables from parent to child modules:
    • Enables hierarchical organization and promotes code reusability.
    • Ensures consistency in variable values across related modules.

Additional Considerations:

  • Terraform workspaces: Variables can be defined at the workspace level, allowing you to manage different environments (e.g., development, staging, production) with the same codebase.
  • Terraform Cloud/Enterprise: These platforms offer features like variable sets and remote state management, which can simplify variable management and collaboration.

By understanding the different methods for passing variables to Terraform modules and following best practices, you can write more organized, reusable, and maintainable infrastructure code.

Summary

Method Description Example Priority
.tfvars files Define variables in a separate file with .tfvars extension. variables.tfvars:
region = "us-west-2"
instance_type = "t2.micro"
Usage: terraform plan -var-file=variables.tfvars
1 (highest)
Command-line arguments Pass variables directly when running Terraform commands. terraform apply -var 'region=us-east-1' -var 'instance_type=t3.medium' 1 (highest)
Environment variables Set environment variables prefixed with TF_VAR_. export TF_VAR_region="eu-central-1"
export TF_VAR_instance_type="m5.large"
terraform apply
2
Module definition Declare variables within the module's .tf file. variable "region" { type = string }
variable "instance_type" { type = string, default = "t2.micro" }
3
Parent-child module passing Pass variables as arguments within the module block in the parent module. module "child_module" {
source = "./path/to/child/module"
region = var.region
instance_type = var.instance_type
}
3
Default values Define default values for variables within the module definition. variable "instance_type" { type = string, default = "t2.micro" } 4 (lowest)

Conclusion

Passing variables to Terraform modules is crucial for creating flexible and reusable infrastructure code. This article explored five methods: using .tfvars files, command-line arguments, environment variables, defining variables within modules, and passing variables from parent to child modules. Each method offers unique advantages and suits different scenarios. Understanding the order of precedence Terraform uses when resolving variable values is essential for predictable outcomes. By choosing the appropriate method and following best practices, you can write well-organized, adaptable, and maintainable Terraform code for robust infrastructure management.

References

  • Input Variables - Configuration Language | Terraform | HashiCorp ... Input Variables - Configuration Language | Terraform | HashiCorp ... | When you declare variables in the root module of your configuration, you can set their values using CLI options and environment variables. When you declare them ...
  • Passing Variables from Root to Child Modules : r/Terraform Passing Variables from Root to Child Modules : r/Terraform | Posted by u/jtl2424 - 8 votes and 13 comments
  • Terraform .tfvars files: Variables Management with Examples Terraform .tfvars files: Variables Management with Examples | .tfvars files are the best and most common way to manage variables in Terraform. Learn how to use them effectively in your IaC projects.
  • Pass .tfvars file to module · Issue #32508 · hashicorp/terraform · GitHub Pass .tfvars file to module · Issue #32508 · hashicorp/terraform · GitHub | Terraform Version > tf version Terraform v1.3.7 on darwin_arm64 + provider registry.terraform.io/hashicorp/aws v4.50.0 Use Cases Simplify passing variables to Modules. I've have been seeing more an...
  • How to work with JSON - Terraform - HashiCorp Discuss How to work with JSON - Terraform - HashiCorp Discuss | Hello everyone, hope somebody can help me with my issue. I need some help on understanding how to work with a JSON full of variables that I’d like to use in my terraform file in order to create my infrastructure. Is this even possible? from what I was able to see, it is possible but I was not able to find a good example that shows me how to do it. The JSON that I want to use has simple varibles and arrays of arrays (meaning that is not just a simple JSON). Do I need to declare, in a variables.t...
  • Variables for CLI or tfvars not being passed to modules · Issue ... Variables for CLI or tfvars not being passed to modules · Issue ... | Is there something wrong with passing variables to modules or am I completely reading the documentation wrong? I've got a project I've broken into the following directory structure. master.tf varia...
  • Main.tf not detecting TF_VARs I setup - Terraform - HashiCorp Discuss Main.tf not detecting TF_VARs I setup - Terraform - HashiCorp Discuss | I have terraform code that follows the following structure → main dir main.tf state.tf versions.tf → modules/eks dir eks.tf variables.tf aws.tf versions.tf my variables.tf looks like this: variable "environment" { type = string } variable "region" { type = string } My main.tf looks like this module "aws-deploy" { source = "../../modules/eks" I am sourcing an .env file initially before doing terraform init and terraform plan the .env file looks like # Cloud Provider ex...
  • Terraform Input Variables using -var-file Argument - STACKSIMPLIFY Terraform Input Variables using -var-file Argument - STACKSIMPLIFY | Share Terraform Modules in Private Modules Registry; Terraform azure ... Provide Input Variables using .tfvars file with CLI argument -var-file ...
  • Trying to understand input variables - tfvars/variables.tf - Terraform ... Trying to understand input variables - tfvars/variables.tf - Terraform ... | Terraform noob here. Quick question. We have a project where we have variables defined in variables.tf(magma/variables.tf at master · magma/magma · GitHub) and I’m trying to override the required variables by using tfvars file. root@ac19040aa1c7:~/tf# terraform plan -target=module.orc8r -var-file="infra.tfvars.json" Warning: Value for undeclared variable The root module does not declare a variable named "orc8r_domain_name" but a value was found in file "infra.tfvars.json". To use this value,...

Were You Able to Follow the Instructions?

😍Love it!
😊Yes
😐Meh-gical
😞No
🤮Clickbait