Terraform Use Output from Another Module: Effective Guide

Estimated reading time: 11 minutes

Last updated on October 25th, 2024 at 02:55 pm

Introduction to Terraform Modules

What are Terraform Modules?

Terraform modules are reusable and shareable code-based, which can be versioned and packaged to encapsulate the infrastructure.

Markdown
Big Single ( main.tf ) = Multiple Small ( modules.tf )

You can break a big chunk of your infrastructure into smaller and resellable code units that you can use across your projects and different parts of your Terraform configuration files.

Why do you need a terraform module? To answer this question let’s check the benefits of using the Terraform Module

Benefits of Using Terraform Modules

  • Code Reusability: Write the code once and use it multiple times with modules.
  • Organization: Break down complex code into smaller but manageable modules.
  • Consistency: Consistency across the projects. Deploy similar infrastructure in the same way.

In summary, using the Terraform modules helps to break the complex code into reusable code that deploys consistently across the environment.

Terraform Use Output from Another Module Benefits
Terraform Use Output from Another Module Benefits

So far we understand the Terraform modules and the benefits of using them. Let’s explore the importance of data sharing and Terraform use output from another module.

Importance of Sharing Data Between Modules

When you split the Terraform module into smaller code, sharing the data between the modules is crucial for the infrastructure. Sharing the data across the module enables you to utilize Terraform output from another module effectively.

For example, the network module outputs the subnet IDs, which later can be passed and utilized inside the compote module. Subnet IDs can be used to create the computer instances.

DevOps Efficiency Hacks in Your Inbox! 📩

Stop wasting time searching. Get weekly tips & tutorials to streamline your DevOps workflow.

Subscribe Now!

Understanding Terraform Outputs

What is a Terraform Output?

Terraform output is exposed values that can be derived from the remote infrastructure or other modules. In simple terms, when you run the terraform plan or terraform apply, it checks the remote state and outputs the values from it.

Later you can use the value from Terraform output in another module. By default, Terraform doesn’t output all the values, you need to define the output block to display the values you want.

Let’s check how to output certain values with Terraform modules.

How to Define Outputs in Terraform Modules

To define an output in the Terraform module, you can use the output block:

HCL
output "subnet_id" {
  value = aws_subnet.production_subnet.id
}

Best Practices for Managing Terraform Modules Outputs

1. Meaningful Naming

Rather than using random names, make the output easily understandable. Using descriptive names makes your Terraform configuration more readable and maintainable. Meaningful names clearly define what they represent without checking the module code.

Instead of using the name like id, use the name like vpc_id

HCL
output "vpc_id" {
  value = aws_vpc.production.id
  description = "The ID of the Prod VPC"
}
2. Only Expose Required Values

Minimize the output and only output the required and non-sensitive values to maintain a secure and clear Terraform configuration.

Always review and adjust the output values to avoid accidental data leaks and security incidents.

HCL
# Avoid exposing internal resources unless necessary
# output "app_s3_bucket_arn" {
#   value = aws_s3_bucket.app.arn
# }

output "s3_bucket_name" {
  value       = aws_s3_bucket.app.name
  description = "The name of the S3 bucket used for application storage"
}
3. Module Documentation

Write the documentation within the output blocks to help users understand the meaning. Comprehensive documentation is important when multiple team members work with the same Terraform configuration.

HCL
output "database_endpoint" {
  value       = aws_db_instance.production.endpoint
  description = "The endpoint of the primary database used for application connections"
}

Terraform Use Output from Another Module: Step-by-Step

Before you start, I assume you already have the Terraform installed on your system. If not you can download it from the official Terraform Website.

Let’s start with initializing the Terraform project by running the terraform init. The process will set the necessary backend configuration and download the required providers

Bash
terraform init

Defining Outputs in the Source Module

Let’s define the output in your source code for the simple network module that outputs the subnet ID:

HCL
# modules/network/main.tf
resource "aws_vpc" "dev_vpc" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "dev_subnet" {
  vpc_id     = aws_vpc.dev_vpc.id
  cidr_block = "10.0.1.0/24"
}

output "subnet_id" {
  value = aws_subnet.dev_subnet.id
}

The above code snippet shows the output subnet_id for the network module.

Mistake to Avoid
  • Undefined Resource: Make sure the resource you are referencing is defined.
  • Incorrect Output: Use consistent and clear output names.

Terraform Use Output from Another Module

To use the output from another module, you need to take references. Terraform Use Output from another module is straightforward:

HCL
# modules/network/main.tf
module "network" {
  source = "./modules/network"
}

# modules/compute/main.tf
module "compute" {
  source     = "./modules/compute"
  subnet_id  = module.network.subnet_id
}

To reference an output from another module, use the following syntax:

HCL
module.<MODULE_NAME>.<OUTPUT_NAME>.

Let’s check the real example by using the subnet_id with compute module:

HCL
# modules/compute/main.tf
resource "aws_instance" "example" {
  ami           = "ami-0c55b129cbfafe1f0"
  instance_type = "t2.micro"
  subnet_id     = var.subnet_id
}

variable "subnet_id" {
  description = "The ID of the subnet to deploy instances into"
  type        = string
}

Level Up Your DevOps Skills! 📈

Get Weekly Tips, Tutorials & Master the Latest Trends – Subscribe Now!

Subscribe Now!

Terraform Use Output from Another Module: Advanced Usage

1. Chain Multiple Module Outputs

You can chain output by passing one output from another module as input.

HCL
module "network" {
  source = "./modules/network"
}

module "database" {
  source     = "./modules/database"
  subnet_id  = module.network.subnet_id
}

module "app" {
  source     = "./modules/app"
  subnet_id  = module.network.subnet_id
  db_id      = module.database.db_id
}

2. Conditional Logic with Module Outputs

You can manage different environments such as staging, production with parameterized modules

HCL
variable "environment" {
  description = "The deployment environment (staging, production)"
  type        = string
}

output "environment" {
  value = var.environment
}

Terraform Use Output from Another Module: Real-World Example

1. Networking Infrastructure

Setting up the networking infrastructure is an essential step for running resources inside them and for that, you need to share VPC and subnet IDs across the modules. The Terraform Use Output from Another Module helps to achieve it

Let’s define the network module with VPC and Subnet.

HCL
# modules/network/main.tf
resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "public" {
  vpc_id     = aws_vpc.vpc.id
  cidr_block = "10.0.1.0/24"
}

resource "aws_subnet" "private" {
  vpc_id     = aws_vpc.vpc.id
  cidr_block = "10.0.2.0/24"
}

output "vpc_id" {
  value = aws_vpc.vpc.id
  description = "The ID of the VPC"
}

output "public_subnet_id" {
  value = aws_subnet.public.id
  description = "The ID of the public subnet"
}

output "private_subnet_id" {
  value = aws_subnet.private.id
  description = "The ID of the private subnet"
}

Now use the VPC and subnet IDs from the network modules for compute instance

HCL
# main.tf
module "network" {
  source = "./modules/network"
}

module "compute" {
  source       = "./modules/compute"
  vpc_id       = module.network.vpc_id
  subnet_id    = module.network.public_subnet_id
}

# modules/compute/main.tf
variable "vpc_id" {
  description = "The ID of the VPC to deploy instances into"
  type        = string
}

variable "subnet_id" {
  description = "The ID of the subnet to deploy instances into"
  type        = string
}

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  subnet_id     = var.subnet_id
}

2. Multi-Region Deployment with Terraform

Deploying the infrastructure across multiple regions with AWS can be a complicated setup but Terraform Use Output from Another Module helps to manage and define resources efficiently.

Let’s define the network module as an essential step

HCL
# modules/network/main.tf
variable "region" {
  description = "The AWS region to deploy the VPC"
  type        = string
}

provider "aws" {
  region = var.region
}

resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"
}

output "vpc_id" {
  value = aws_vpc.vpc.id
  description = "The ID of the VPC"
}

Now define the different regions and pass the VPC IDs

HCL
# main.tf
module "network_us_east_1" {
  source = "./modules/network"
  region = "us-east-1"
}

module "network_us_west_2" {
  source = "./modules/network"
  region = "us-west-2"
}

module "compute_us_east_1" {
  source    = "./modules/compute"
  vpc_id    = module.network_us_east_1.vpc_id
}

module "compute_us_west_2" {
  source    = "./modules/compute"
  vpc_id    = module.network_us_west_2.vpc_id
}

3. Microservices Architecture

Microservice architecture deployment can be complex, the deployment is to be carried out in a specific subnet for service isolation and enhanced security. Terraform Use Output from Another Module helps to coordinate the microservices deployment.

Let’s create the first network and different subnets for services

HCL
# modules/network/main.tf
resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "service_backend" {
  vpc_id     = aws_vpc.vpc.id
  cidr_block = "10.0.1.0/24"
}

resource "aws_subnet" "service_frontend" {
  vpc_id     = aws_vpc.vpc.id
  cidr_block = "10.0.2.0/24"
}

output "vpc_id" {
  value = aws_vpc.vpc.id
  description = "The ID of the VPC"
}

output "service_backend_subnet_id" {
  value = aws_subnet.service_backend.id
  description = "The ID of the subnet for Service Backend"
}

output "service_frontend_subnet_id" {
  value = aws_subnet.service_frontend.id
  description = "The ID of the subnet for Service Frontend"
}

Now within the service module, you can use the Terraform output

HCL
# main.tf
module "network" {
  source = "./modules/network"
}

module "service_backend" {
  source    = "./modules/service_a"
  subnet_id = module.network.service_backend_subnet_id
}

module "service_frontend" {
  source    = "./modules/service_b"
  subnet_id = module.network.service_frontend_subnet_id
}

# modules/service_a/main.tf
variable "subnet_id" {
  description = "The ID of the subnet to deploy Service A into"
  type        = string
}

resource "aws_instance" "service_backend_instance" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  subnet_id     = var.subnet_id
}

# modules/service_b/main.tf
variable "subnet_id" {
  description = "The ID of the subnet to deploy Service B into"
  type        = string
}

resource "aws_instance" "service_frontend_instance" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  subnet_id     = var.subnet_id
}

You can effectively manage the complex Terraform configuration such as modular architecture, multi-region deployment, and microservice infrastructure.

Conclusion

Key Points
  • Terraform modules enhance reusability and code organization
  • Output blocks are crucial for data sharing between modules
  • Properly define and reference outputs in configuration.
Tips for Effective Module Output Management
  • Use descriptive and meaningful names.
  • Only expose necessary values. Excessive output can slow down Terraform runs.
  • Documents your outputs.

Terraform Use Output from Another Module: FAQs

Can I use outputs from multiple modules simultaneously?

Yes, you can use outputs from multiple modules by referencing each module’s output block.

How do I debug issues with module outputs?

Use terraform plan to see how Terraform understands your configuration. Check the definitions and references of your output

What are the limitations of using module outputs in Terraform?

Only supported data types and expressions can be used with the Terraform output. Ensure outputs are simple and well-defined.

Kashyap Merai
Kashyap Merai

Kashyap Merai, a Certified Solution Architect and Public Cloud Specialist with over 7 years in IT. He helped startups in Real Estate, Media Streaming, and On-Demand industries launch successful public cloud projects.

Passionate about Space, Science, and Computers, He also mentors aspiring cloud engineers, shaping the industry's future.

Connect with him on LinkedIn to stay updated on cloud innovations.