🐶
Terraform

Terraform Module Output References: A How-To Guide

By Filip on 10/07/2024

Learn how to effectively reference and utilize resources created by Terraform modules in your infrastructure code.

Terraform Module Output References: A How-To Guide

Table of Contents

Introduction

Terraform modules are a powerful way to organize and reuse your infrastructure code. Often, you'll need to use resources created in one module within another module. This guide explains how to pass resource information between Terraform modules using outputs and references.

Step-by-Step Guide

To use a resource created in one Terraform module within another module, you need to follow these steps:

  1. Output the necessary values from the source module:

    • In the module where the resource is defined, use the output block to expose the attributes of the resource you want to reference.
    • Give the output a descriptive name. This name will be used to reference the value in other modules.
  2. Reference the output in the consuming module:

    • In the module where you want to use the resource, reference the output value using the following syntax: module.<MODULE_NAME>.<OUTPUT_NAME>.
    • Replace <MODULE_NAME> with the name of the module where the output is defined.
    • Replace <OUTPUT_NAME> with the name of the output you want to use.

Example:

Let's say you have a module named "networking" that creates a VPC and outputs its ID:

# networking/outputs.tf
output "vpc_id" {
  value = aws_vpc.main.id
}

Now, you have another module named "compute" that needs to create an EC2 instance within that VPC:

# compute/main.tf
resource "aws_instance" "example" {
  # ... other configurations ...
  subnet_id = module.networking.vpc_id 
}

module "networking" {
  source = "../networking"
  # ... other configurations ...
}

In this example:

  • The "networking" module outputs the VPC ID as vpc_id.
  • The "compute" module references this output as module.networking.vpc_id when defining the subnet_id for the EC2 instance.

Important Notes:

  • You can only reference values that are explicitly defined as outputs in the source module.
  • Terraform's module system ensures that resources are created and destroyed in the correct order based on these dependencies.
  • Using outputs and modules promotes code reusability and maintainability in your Terraform projects.

Code Example

This code demonstrates how to use Terraform modules to create a VPC and launch an EC2 instance in it. The networking module defines a VPC and outputs its ID. The compute module defines an EC2 instance and takes the VPC ID as an input. The root module calls both modules and passes the VPC ID from the networking module to the compute module. This allows for reusable infrastructure components and managed dependencies between them.

This example demonstrates how to create a VPC in one module and use its ID to launch an EC2 instance in another module.

1. Networking Module (networking)

This module creates a VPC and outputs its ID.

# networking/variables.tf
variable "vpc_cidr" {
  description = "The CIDR block for the VPC"
  type = string
  default = "10.0.0.0/16"
}

# networking/main.tf
resource "aws_vpc" "main" {
  cidr_block = var.vpc_cidr
  enable_dns_hostnames = true
  enable_dns_support = true

  tags = {
    Name = "main-vpc"
  }
}

# networking/outputs.tf
output "vpc_id" {
  value = aws_vpc.main.id
  description = "The ID of the VPC"
}

2. Compute Module (compute)

This module creates an EC2 instance and takes the VPC ID as an input from the networking module.

# compute/variables.tf
variable "vpc_id" {
  description = "The ID of the VPC to launch the instance in"
  type = string
}

# compute/main.tf
resource "aws_instance" "example" {
  ami = "ami-0c55b159c9e670235" # Replace with your desired AMI ID
  instance_type = "t2.micro"
  subnet_id = var.vpc_id

  tags = {
    Name = "example-instance"
  }
}

module "networking" {
  source = "../networking"
}

3. Root Module (main.tf)

This module calls both the networking and compute modules.

module "networking" {
  source = "./networking"
}

module "compute" {
  source = "./compute"
  vpc_id = module.networking.vpc_id
}

Explanation:

  • The networking module defines a VPC and outputs its ID using the output block.
  • The compute module defines an EC2 instance and takes the VPC ID as an input variable.
  • The root module calls both modules and passes the vpc_id output from the networking module to the compute module using module.networking.vpc_id.

This example demonstrates how to use Terraform modules to create reusable infrastructure components and manage dependencies between them. By using outputs and module references, you can create complex infrastructure deployments while maintaining code clarity and reusability.

Additional Notes

  • Data Types: Ensure the output's data type matches the expected input variable type in the consuming module. Type mismatches can lead to errors.
  • Implicit Dependencies: Terraform automatically manages dependencies between resources and modules based on how they reference each other. You generally don't need to explicitly define dependencies unless you have complex scenarios.
  • Module Composition: You can nest modules within each other to create more complex and organized infrastructure deployments. Outputs from inner modules can be passed up to higher-level modules.
  • Remote State: When using remote state, ensure both modules have access to the state file where the resource information is stored.
  • Alternative to Outputs: For simple values, you can pass variables directly from one module to another. However, outputs provide better encapsulation and reusability.
  • Security Considerations: Be mindful of sensitive information when outputting values from modules. Avoid exposing secrets directly and consider using tools like Vault for secure secret management.
  • Testing: Test your modules in isolation and together to ensure they interact correctly and produce the desired infrastructure.
  • Documentation: Clearly document your modules, including their inputs, outputs, and any dependencies, to improve maintainability and collaboration.
  • Versioning: Use a version control system like Git to track changes to your modules and enable rollbacks if needed. Consider using semantic versioning to communicate changes to your module's API.

Summary

This table summarizes how to use resources from one Terraform module in another:

| Step | Source Module | Consuming Module

Conclusion

By using outputs and module references, you can create modular, reusable, and maintainable Terraform code for managing your infrastructure. This approach not only improves code organization but also enhances collaboration and reduces the risk of errors during deployments. Remember to follow best practices for documentation, version control, and security to maximize the benefits of using Terraform modules in your projects.

References

Were You Able to Follow the Instructions?

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