🐶
Terraform

Terraform Child Module Variable Passing Strategies

By Filip on 10/07/2024

Learn how to effectively pass variables from a Terraform root module to a child module for streamlined infrastructure provisioning and increased code reusability.

Terraform Child Module Variable Passing Strategies

Table of Contents

Introduction

In Terraform, modules promote code reusability and organization. To leverage this effectively, you often need to pass data, such as variables, from a root module to a child module. This allows for customization and dynamic configuration of the child module's behavior. This article outlines the steps to pass variables from a root module to a child module in Terraform, enabling seamless data flow and modularity in your infrastructure code.

Step-by-Step Guide

To pass variables from a root module to a child module in Terraform, follow these steps:

  1. Define the variable in the child module:

    • In the child module's variables.tf file, declare the variable using the variable block.
    • Specify the variable's name and optionally its type, description, and default value.
  2. Pass the variable value from the root module:

    • In the root module's main.tf or a similar file, locate the module block where you call the child module.
    • Inside the module block, assign a value to the child module's variable using the variable's name as the key.
    • You can pass values directly, reference other variables, or use expressions.

Example:

# child-module/variables.tf
variable "instance_name" {
  type        = string
  description = "Name of the instance"
}
# root-module/main.tf
module "child" {
  source = "../child-module"
  instance_name = "my-instance"
}

Additional Notes:

  • You can pass any valid Terraform value as a variable, including strings, numbers, lists, maps, and objects.
  • If a variable is declared in both the root and child modules, the value passed from the root module takes precedence.
  • You can use .tfvars files to define variable values externally and pass them to both root and child modules.
  • It is not currently possible to pass resources directly as variables to modules.
  • When using complex data structures, ensure the structure matches between the variable definition in the child module and the value passed from the root module.
  • Use clear and descriptive variable names to improve code readability and maintainability.

Code Example

This code demonstrates passing variables from a root Terraform module to child modules. It defines a network module with variables for VPC and subnet CIDR blocks, and a server module with variables for instance name and subnet ID. The root module calls both child modules, passing values for their respective variables. The server module receives the subnet ID from an output of the network module, illustrating how to use outputs from one module as input for another.

This example demonstrates passing variables from a root module to a child module in Terraform.

Project Structure:

terraform-modules/
├── network/
│   └── variables.tf
└── server/
    ├── variables.tf
    └── main.tf

1. Child Module (network/variables.tf):

variable "vpc_cidr_block" {
  type        = string
  description = "The CIDR block for the VPC"
}

variable "subnet_cidr_block" {
  type        = string
  description = "The CIDR block for the subnet"
}

2. Child Module (server/variables.tf):

variable "instance_name" {
  type        = string
  description = "Name of the EC2 instance"
}

variable "subnet_id" {
  type        = string
  description = "ID of the subnet to deploy the instance in"
}

3. Root Module (server/main.tf):

module "network" {
  source = "../network"
  vpc_cidr_block = "10.0.0.0/16"
  subnet_cidr_block = "10.0.1.0/24"
}

module "server" {
  source = "./"
  instance_name = "my-instance"
  subnet_id = module.network.subnet_id # Accessing output from network module
}

Explanation:

  • network/variables.tf: Defines variables for VPC and subnet CIDR blocks.
  • server/variables.tf: Defines variables for instance name and subnet ID.
  • server/main.tf:
    • Calls the network module and passes values for vpc_cidr_block and subnet_cidr_block.
    • Calls the server module (itself in this case) and passes values for instance_name and subnet_id.
    • The subnet_id value is retrieved from the output of the network module using module.network.subnet_id.

This example demonstrates how to define variables in child modules and pass values to them from the root module. It also shows how to access outputs from other modules and use them as input for other modules.

Additional Notes

  • Understanding Variable Scope: Variables in Terraform have a specific scope. A variable defined in a child module is only accessible within that child module unless explicitly passed down from a parent module.

  • Output Values as Inputs: You can use the output values of one module as input variables for another. This is illustrated in the example where module.network.subnet_id fetches the subnet ID output from the network module and passes it to the server module.

  • Data Encapsulation: Modules help encapsulate data and logic. By passing variables, you control the information flow between modules, promoting better organization and reducing unintended side effects.

  • Reusability and Consistency: Modules, combined with variable passing, encourage code reusability. You can define a module once (e.g., for creating a network configuration) and reuse it across different parts of your infrastructure, customizing its behavior through variables.

  • Terraform State: Remember that Terraform manages the state of your infrastructure. When you change variable values passed to modules, Terraform will detect these changes and apply the necessary updates during the next terraform apply.

Summary

Step Description Example
1. Define Variable in Child Module - Declare the variable in the child module's variables.tf file using the variable block.
- Specify the variable's name, and optionally its type, description, and default value.
terraform <br> # child-module/variables.tf <br> variable "instance_name" { <br> &nbsp;&nbsp; type = string <br> &nbsp;&nbsp; description = "Name of the instance" <br> } <br>
2. Pass Variable Value from Root Module - Locate the module block in your root module's main.tf (or similar) where you call the child module.
- Inside the module block, assign a value to the child module's variable using its name as the key.
- You can pass values directly, reference other variables, or use expressions.
terraform <br> # root-module/main.tf <br> module "child" { <br> &nbsp;&nbsp; source = "../child-module" <br> &nbsp;&nbsp; instance_name = "my-instance" <br> } <br>

Key Points:

  • You can pass any valid Terraform value as a variable.
  • Root module variable values take precedence over child module defaults.
  • Use .tfvars files to manage variable values externally.
  • Passing resources directly as variables is not supported.
  • Ensure complex data structures match between root and child modules.
  • Use clear and descriptive variable names for better code readability.

Conclusion

Passing variables from root to child modules is fundamental for creating modular and reusable Terraform code. By defining variables in child modules and passing values from the root module, you can customize the behavior of your infrastructure deployments. This approach promotes code organization, maintainability, and consistency, ultimately leading to more efficient and scalable infrastructure management. Understanding variable scope, leveraging output values as inputs, and adhering to Terraform's best practices for module composition are essential for harnessing the full potential of modular design in your infrastructure as code.

References

Were You Able to Follow the Instructions?

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