Module Outputs
Categories:
3 minute read
Terraform module outputs allow users to expose information about the resources created or modified by a module to the calling code, making it easier to consume and use that information in downstream resources.
Retrieve output
values from an upstream resource to use in a downstream deployment
For example, we have a module that creates an AWS RDS database and we need to get the database’s name
, address
, and port
number to use in the module of a downstream application such as a website that needs to connect to the database.
The AWS RDS
resource’s reusable module
needs to declare the required output
values in its code. Normally this is written to an outputs.tf
file as shown below.
output "db_name" {
value = aws_db_instance.example.db_name
description = "The name of the MysqL database"
}
output "address" {
value = aws_db_instance.example.address
description = "The address of the MysqL database"
}
output "port" {
value = aws_db_instance.example.port
description = "The port of the MysqL database"
}
The AWS RDS
resource’s root module
then needs to declare the required output
values in its code, but this time we refer to the module as the source instead of the actual resource. This is normally written to an outputs.tf
file as shown below.
Note the value
string is prefixed with module
and then refers to the module
name defined in the root module main.tf
file then the output name as declared in the resuable output.tf file.
output "db_name" {
value = module.mysql-database.db_name
description = "The name of the MysqL database"
}
output "address" {
value = module.mysql-database.address
description = "The address of the MysqL database"
}
output "port" {
value = module.mysql-database.port
description = "The port of the MysqL database"
}
By combining these two output declarations, when we run the root module code the output values are written to the AWS RDS state file.
{
"version": 4,
"terraform_version": "1.3.9",
"serial": 8,
"lineage": "06236362-58a9-8c99-2b2d-6010f00502ec",
"outputs": {
"address": {
"value": "exaple20240394081723843100000001.cmfhmsgsgs4ejd.us-east-2.rds.amazonaws.com",
"type": "string"
},
"db_name": {
"value": "exampledatabase",
"type": "string"
},
"port": {
"value": 3306,
"type": "number"
}
},
...state file continues
In the downstream resource module (a web site for example), we can refer to the AWS RDS state file
as a data
source and extract the values from the output block. In the web site reusable module
we require two data
blocks.
The first data
block is the source that defines where the state file of the AWS RDS
instance is located. The example below is written for an AWS S3 bucket and uses input variables provided at the root module for the paramter values. The result of this code will a target string value we can use of data.terraform_remote_state.db
.
The terraform_remote_state
block that declares the location of the state file for the AWS RDS instance
data "terraform_remote_state" "db" {
backend = "s3"
config = {
bucket = var.db_remote_state_bucket
key = var.db_remote_state_key
region = var.region
}
}
In the second data
block we then use the S3 target string value and append what we want to retrieve from the state file, which in this example is from the output
section created above plus the values name
, address
, and port
. These values are part of a data block that define values in a web site configuration that is setup via a bash script.
data "template_file" "user_data" {
template = file("${path.module}/user-data.sh")
vars = {
db_name = data.terraform_remote_state.db.outputs["name"]
db_address = data.terraform_remote_state.db.outputs["address"]
db_port = data.terraform_remote_state.db.outputs["port"]
}
}