How to use outputs to expose Terraform provisioned resources

Updated: February 3, 2024 By: Guest Contributor Post a comment

Introduction

Terraform, a popular infrastructure as code tool, enables engineers to define and provision infrastructure through code. An essential feature within Terraform is the use of outputs, which can expose information about your infrastructure’s elements, making the automation and management processes more efficient and transparent.

Outputs serve as a mechanism for extracting information about the resources Terraform manages, at times for use by other Terraform configurations, or simply for informing users. Knowing how to effectively use outputs can greatly enhance your Terraform projects. This tutorial covers the basics to more advanced uses of outputs, complete with examples.

What are Terraform Outputs?

Before diving into the advanced functionalities, it’s crucial to understand what outputs are and why they are beneficial. Outputs in Terraform are declared in your configuration files, typically towards the end. They can be leveraged to display specific information about your resources after Terraform completes its apply operation. For example, after provisioning a virtual machine, you might want to output its IP address.

output "instance_ip" {
  value = aws_instance.my_instance.public_ip
}

This simple output declaration will display the public IP address of the EC2 instance named my_instance once Terraform completes the provisioning.

Basic Output Usage

Building on the basics, let’s dive into more functional examples of using outputs to enhance your project’s transparency and automation capabilities.

Exposing Basic Resource Information

output "db_password" {
  value = aws_db_instance.my_db.password
  sensitive = true
}

This output exposes the password for a database instance, marking it as sensitive to prevent it from appearing in CLI outputs or logs, hence maintaining security.

Using Outputs Across Modules

Terraform supports modular infrastructure development. Outputs can be critical in passing information between modules. Below is an example of how you might output a resource’s detail from one module to be used in another.

module "vpc" {
  source = "./modules/vpc"
}

output "vpc_id" {
  value = module.vpc.vpc_id
}

This indicates how a VPC’s ID is exposed from a VPC module for use, potentially by other modules or resources.

Intermediate Output Usage

Moving into more intricate usage scenarios, Terraform’s capability to handle dynamic outputs through the use of complex data structures and functions becomes apparent.

Aggregating Outputs

Suppose your infrastructure definition creates multiple instances or resources and you’d like to aggregate certain information about these resources. You might use a combination of lists and the join function as demonstrated below:

output "instance_ips" {
  value = join(", ", aws_instance.web.*.public_ip)
}

This output will concatenate and display the public IP addresses of all the instances created as part of the web configuration.

Advanced Output Usage

As your Terraform projects grow in complexity, you might find yourself needing to expose intricate details or interact with external data sources. Here, we delve into advanced examples that showcase outputs’ flexibility and power.

Outputs as Inputs to Other Resources

Sometimes, you’ll want to use outputs from one resource as inputs for another, creating a dependency chain that Terraform can understand and manage effectively. Consider a DNS module that requires the IP address of a server:

output "server_ip" {
  value = aws_instance.server.public_ip
}

resource "dns_record" "example" {
  name = "example.com"
  type = "A"
  value = output.server_ip
}

Such a configuration ensures that your DNS records are dynamically updated based on the provisioned server’s outputted IP address.

Using External Data Sources with Outputs

Outputs can also interact with external data sources to enrich the information being exposed or to drive further automation. For example, using the http provider to fetch data:

data "http" "example" {
  url = "https://api.example.com/status"
}

output "external_api_status" {
  value = data.http.example.body
}

This demonstrates leveraging external APIs within your Terraform configurations, using output to expose the external data.

Conclusion

Understanding and utilizing outputs within Terraform can drastically improve the insight into your provisioned resources and facilitate advanced automation and integration possibilities. Starting with basic use cases and advancing through to more complex scenarios demonstrates outputs’ flexibility and power in infrastructure management. Whether for exposing sensitive resource information securely, linking resources across modules, or integrating external data, mastering outputs will enhance your Terraform proficiency.