Module Outputs

Terraform module outputs are values that a module can return to the calling code to expose information about the resources it created or modified.

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"]
  }
}
Last modified July 21, 2024: update (e2ae86c)