Learn how to seamlessly pass data and outputs from one Terraform template to another using output variables as input variables for streamlined infrastructure provisioning.
In Terraform, modules promote code reusability and organization. Often, you'll need to pass data, such as resource identifiers, between these modules. This guide demonstrates how to use the output of one Terraform module as an input variable in another, enabling seamless data flow and resource dependencies within your infrastructure code.
To use the output of one Terraform module as an input variable in another, you'll leverage Terraform's terraform_remote_state
resource.
1. Define Outputs in the Source Module:
In the Terraform module where the resource you want to reference is defined, declare an output variable. This makes the value available to other modules.
output "example_output" {
value = aws_instance.example.id
}
2. Create a terraform_remote_state
Data Source:
In the module where you want to use the output value, define a terraform_remote_state
data source. This data source allows you to access the state of another Terraform deployment.
data "terraform_remote_state" "source_module" {
backend = "local"
config = {
path = "../source-module/terraform.tfstate"
}
}
"../source-module/terraform.tfstate"
with the relative path to the state file of your source module.3. Access the Output Value:
You can now access the output value from the source module using the data.terraform_remote_state
object.
resource "aws_instance" "example" {
# ... other configurations ...
subnet_id = data.terraform_remote_state.source_module.outputs.subnet_id
}
"source_module"
with the name you gave your terraform_remote_state
data source."subnet_id"
with the name of the output variable you defined in the source module.Important Considerations:
terraform_remote_state
configuration correctly points to the source module's state file.terraform_remote_state
data source will always be applied after the source module.backend
and config
settings in the terraform_remote_state
data source accordingly.This code demonstrates Terraform module communication. The first module defines network infrastructure (VPC and subnet) and outputs the subnet ID. The second module, responsible for creating an EC2 instance, accesses the first module's state file to retrieve the subnet ID and uses it during instance creation, ensuring the instance is provisioned within the intended subnet. This showcases how modules can interact to build upon each other's resources.
Let's say you have two Terraform modules:
1. networking/main.tf:
# Defines a VPC
resource "aws_vpc" "example" {
cidr_block = "10.0.0.0/16"
}
# Defines a subnet
resource "aws_subnet" "example" {
vpc_id = aws_vpc.example.id
cidr_block = "10.0.1.0/24"
}
# Makes the subnet ID available as an output
output "subnet_id" {
value = aws_subnet.example.id
}
2. compute/main.tf:
# Accesses the state of the networking module
data "terraform_remote_state" "networking" {
backend = "local"
config = {
path = "../networking/terraform.tfstate"
}
}
# Creates an EC2 instance
resource "aws_instance" "example" {
ami = "ami-0c55b159c9e670260" # Replace with your desired AMI
instance_type = "t2.micro"
# Uses the subnet ID from the networking module
subnet_id = data.terraform_remote_state.networking.outputs.subnet_id
}
Explanation:
networking
module defines a VPC and subnet and outputs the subnet ID.compute
module uses a terraform_remote_state
data source to access the state file of the networking
module.compute
module then references the subnet_id
output from the networking
module when creating the EC2 instance.This ensures that the EC2 instance is created in the correct subnet defined by the networking
module.
Note: This example uses a local backend. For remote backends, you'll need to adjust the backend
and config
settings in the terraform_remote_state
data source accordingly.
terraform_remote_state
is particularly useful when refactoring existing code into modules. You can extract resources into a separate module and use terraform_remote_state
to access their outputs without rewriting large portions of your codebase.terraform_remote_state
:
terraform output
to retrieve sensitive values directly after deployment rather than storing them in the state.terraform_remote_state
data sources to easily identify their purpose.By understanding these concepts and following best practices, you can effectively use Terraform modules to create well-structured, reusable, and maintainable infrastructure code.
This table summarizes how to use outputs from one Terraform module as input variables in another:
Step | Description | Code Example |
---|---|---|
1. Define Outputs in Source Module | Declare output variables in the module containing the resources you want to reference. | terraform output "example_output" { value = aws_instance.example.id } |
2. Create terraform_remote_state Data Source |
In the consuming module, define a terraform_remote_state data source to access the source module's state. |
terraform data "terraform_remote_state" "source_module" { backend = "local" config = { path = "../source-module/terraform.tfstate" } } |
3. Access the Output Value | Use the data.terraform_remote_state object to access the desired output variable. |
terraform resource "aws_instance" "example" { # ... other configurations ... subnet_id = data.terraform_remote_state.source_module.outputs.subnet_id } |
Key Points:
terraform_remote_state
configuration points to the correct state file.backend
and config
settings for remote state file locations.By leveraging terraform_remote_state
, you can establish connections between your Terraform modules, enabling one module to utilize the outputs of another. This approach enhances code organization, promotes reusability, and ensures a logical flow of information within your infrastructure deployments. Remember to pay close attention to state file locations, especially when working with remote backends, and to follow security best practices when handling sensitive data. By mastering these techniques, you can build robust and maintainable infrastructure as code using Terraform modules.