Tutorial

How To Manage Infrastructure Data with Terraform Outputs

How To Manage Infrastructure Data with Terraform Outputs

Introduction

Terraform outputs are used to extract information about the infrastructure resources from the project state. Using other features of the Hashicorp Configuration Language (HCL), which Terraform uses, resource information can be queried and transformed into more complex data structures, such as lists and maps. Outputs are useful for providing information to external software, which can operate on the created infrastructure resources.

In this tutorial, you’ll learn about Terraform output syntax and its parameters by creating a simple infrastructure that deploys Droplets. You’ll also parse the outputs programmatically by converting them to JSON.

Prerequisites

Note: This tutorial has specifically been tested with Terraform 1.0.2.

Defining Outputs

In this section, you’ll declare a Droplet, deploy it to the cloud, and learn about outputs by defining one that will show the Droplet’s IP address.

From the terraform-outputs directory you created as a prerequisite, create and open the droplets.tf file for editing:

  1. nano droplets.tf

Add the following Droplet resource and output definition:

terraform-outputs/droplets.tf
resource "digitalocean_droplet" "web" {
  image  = "ubuntu-20-04-x64"
  name   = "test-droplet"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

output "droplet_ip_address" {
  value = digitalocean_droplet.web.ipv4_address
}

You first declare a Droplet resource, called web. Its actual name in the cloud will be test-droplet, in the region fra1, running Ubuntu 20.04.

Then, you declare an output called droplet_ip_address. In Terraform, outputs are used to export and show internal and computed values and information about the resources. Here, you set the value parameter, which accepts the data to output, to the IP address of the declared Droplet. At declare time, it’s unknown, but it will become available once the Droplet is deployed. Outputs are shown and accessible after each deployment.

Save and close the file, then deploy the project by running the following command:

  1. terraform apply -var "do_token=${DO_PAT}"

Enter yes to apply when prompted. The end of the output will be similar to this:

Output
... digitalocean_droplet.web: Creating... ... digitalocean_droplet.web: Creation complete after 32s [id=207631771] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Outputs: droplet_ip_address = ip_address

The highlighted IP address belongs to your newly deployed Droplet. Applying the project deploys the resources to the cloud and shows the outputs at the end, when all resource attributes are available. Without the droplet_ip_address output, Terraform would show no further information about the Droplet, except that it’s deployed.

Outputs can also be shown using the output command:

  1. terraform output

The output will list all outputs in the project:

Output
droplet_ip_address = ip_address

You can also query a specific output by name by specifying it as an argument:

  1. terraform output output_name

For droplet_ip_address, the output will consist of the IP address only:

Output
ip_address

Except for specifying the mandatory value, outputs have a few optional parameters:

  • description: embeds short documentation detailing what the output shows.
  • depends_on: a meta parameter available at each resource that allows you to explicitly specify resources the output depends on that Terraform is not able to automatically deduce during planning.
  • sensitive: accepts a boolean value, which prevents the content of the output from being shown after deploying if set to true.

The sensitive parameter is useful when the logs of the Terraform deployment will be publicly available, but the output contents should be kept hidden. You’ll now add it to your Droplet resource definition.

Open droplets.tf for editing and add the highlighted line:

terraform-outputs/droplets.tf
resource "digitalocean_droplet" "web" {
  image  = "ubuntu-20-04-x64"
  name   = "test-droplet"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

output "droplet_ip_address" {
  value      = digitalocean_droplet.web.ipv4_address
  sensitive = true
}

Save and close the file when you’re done. Deploy the project again by running:

  1. terraform apply -var "do_token=${DO_PAT}"

Enter yes when prompted. You’ll see that the output is redacted:

Output
... Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: droplet_ip_address = <sensitive>

Even if it’s marked as sensitive, the output and its contents will still be available through other channels, such as viewing the Terraform state or querying the outputs directly.

In the next step, you’ll create a different Droplet and output structure, so destroy the currently deployed ones by running:

  1. terraform destroy -var "do_token=${DO_PAT}"

The output at the very end will be:

Output
... Destroy complete! Resources: 1 destroyed.

You’ve declared and deployed a Droplet and created an output that shows its IP address. You’ll now learn about using outputs to show more complex structures such as lists and maps.

Outputting Complex Structures

In this section, you’ll deploy multiple Droplets from the same definition using the count keyword, and output their IP addresses in various formats.

Using the for loop

You’ll need to modify the Droplet resource definition, so open it for editing:

  1. nano droplets.tf

Modify it to look like this:

terraform-outputs/droplets.tf
resource "digitalocean_droplet" "web" {
  count  = 3
  image  = "ubuntu-20-04-x64"
  name   = "test-droplet-${count.index}"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

You’ve specified that three Droplets should be created using the count key and added the current index to the Droplet name, so that you’ll be able to later discern between them. Remove the existing output below. When you’re done, save and close the file.

Apply the code by running:

  1. terraform apply -var "do_token=${DO_PAT}"

Terraform will plan the creation of three numbered Droplets, called test-droplet-0, test-droplet-1, and test-droplet-2. Enter yes when prompted to finish the process. You’ll see the following output in the end:

Output
... Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

This means that all three Droplets are successfully deployed and that all information about them is stored in the project state.

The easiest way to access their resource attributes is to use outputs, but creating one for each Droplet is not scalable. The solution is to use the for loop to traverse through the list of Droplets and gather their attributes, or to alternatively use splat expressions (which you’ll learn about later in this step).

You’ll first define an output that will output the IP addresses of the three Droplets, paired with their names. Open droplets.tf for editing:

  1. nano droplets.tf

Add the following lines:

terraform-outputs/droplets.tf
resource "digitalocean_droplet" "web" {
  count  = 3
  image  = "ubuntu-20-04-x64"
  name   = "test-droplet-${count.index}"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

output "droplet_ip_addresses" {
  value = {
    for droplet in digitalocean_droplet.web:
    droplet.name => droplet.ipv4_address
  }
}

The output value of droplet_ip_addresses is constructed using a for loop. Because it’s surrounded by braces, the resulting type will be a map. The loop traverses the list of Droplets, and for each instance, pairs its name with its IP address and appends it to the resulting map.

Save and close the file, then apply the project again:

  1. terraform apply -var "do_token=${DO_PAT}"

Enter yes when prompted and you’ll receive the output contents at the end:

Output
Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: droplet_ip_addresses = { "test-droplet-0" = "ip_address" "test-droplet-1" = "ip_address" "test-droplet-2" = "ip_address" }

The droplet_ip_addresses output details the IP addresses of the three deployed droplets.

Using the Terraform output command, you can get the contents of the output as JSON using its command argument:

  1. terraform output -json droplet_ip_addresses

The result will be similar to the following:

Output
{"test-droplet-0":"ip_address","test-droplet-1":"ip_address","test-droplet-2":"ip_address"}

JSON parsing is widely used and supported in many programming languages. This way, you can programmatically parse the information about the deployed Droplet resources.

Using Splat Expressions

Splat expressions offer a compact way of iterating over all elements of a list, and collecting contents of an attribute from each of them, resulting in a list. A splat expression that would extract the IP addresses of the three deployed droplets would have the following syntax:

digitalocean_droplet.web[*].ipv4_address

The [*] symbol traverses the list on its left and for each of the elements, takes the contents of its attribute specified on the right. If the reference on the left is not a list by itself, it will be converted to one where it will be the sole element.

You can open droplets.tf for editing and modify the following lines to implement this:

terraform-outputs/droplets.tf
resource "digitalocean_droplet" "web" {
  count  = 3
  image  = "ubuntu-20-04-x64"
  name   = "test-droplet-${count.index}"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

output "droplet_ip_addresses" {
  value = digitalocean_droplet.web[*].ipv4_address
}

After saving the file, apply the project by running the following command:

  1. terraform apply -var "do_token=${DO_PAT}"

You’ll receive output that is now a list, and which contains only the IP addresses of the Droplets:

Output
... Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: droplet_ip_addresses = [ "ip_address", "ip_address", "ip_address", ]

To receive the output as JSON, run the following command:

  1. terraform output -json droplet_ip_addresses

The output will be a single array:

Output
["ip_address","ip_address","ip_address"]

You’ve used outputs together with splat expressions and for loops to export the IP addresses of the deployed Droplets. You’ve also received the output contents as JSON, and you’ll now use jq—a tool for dynamically filtering JSON according to given expressions—to parse them.

Parsing Outputs Using jq

In this step, you’ll install and learn the basics of jq, a tool for manipulating JSON documents. You’ll use it to parse the outputs of your Terraform project.

If you’re on Ubuntu, run the following command to install jq:

  1. sudo snap install jq

On macOS, you can use Homebrew to install it:

  1. brew install jq

jq applies the provided processing expression on given input, which can be piped in. The easiest task in jq is to pretty print the input:

  1. terraform output -json droplet_ip_addresses | jq '.'

Passing in the identity operator (.) means that the whole JSON document parsed from the input should be outputted without modifications:

Output
[ "first_ip_address", "second_ip_address", "third_ip_address" ]

You can request just the second IP address using the array bracket notation, counting from zero:

  1. terraform output -json droplet_ip_addresses | jq '.[1]'

The output will be:

Output
"second_ip_address"

To make the result of the processing an array, wrap the expression in brackets:

  1. terraform output -json droplet_ip_addresses | jq '[.[1]]'

You’ll get a pretty printed JSON array:

Output
[ "second_ip_address" ]

You can retrieve parts of arrays instead of single elements by specifying a range of indexes inside the brackets:

  1. terraform output -json droplet_ip_addresses | jq '.[0:2]'

The output will be:

Output
[ "first_ip_address", "second_ip_address" ]

The range 0:2 returns the first two elements—the upper part of the range (2) is not inclusive, so only elements at positions 0 and 1 are fetched.

You can now destroy the deployed resources by running:

  1. terraform destroy -var "do_token=${DO_PAT}"

In this step, you have installed jq and used it to parse and manipulate the output of your Terraform project, which deploys three Droplets.

Conclusion

You have learned about Terraform outputs, using them to show details about the deployed resources and to export data structures for later external processing. You’ve also used outputs to show attributes of a single resource, as well as for showing constructed maps and lists containing resource attributes.

For more detailed information about the features of jq, visit the official docs.

This tutorial is part of the How To Manage Infrastructure with Terraform series. The series covers a number of Terraform topics, from installing Terraform for the first time to managing complex projects.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products


Tutorial Series: How To Manage Infrastructure with Terraform

Terraform is a popular open source Infrastructure as Code (IAC) tool that automates provisioning of your infrastructure in the cloud and manages the full lifecycle of all deployed resources, which are defined in source code. Its resource-managing behavior is predictable and reproducible, so you can plan the actions in advance and reuse your code configurations for similar infrastructure.

In this series, you will build out examples of Terraform projects to gain an understanding of the IAC approach and how it’s applied in practice to facilitate creating and deploying reusable and scalable infrastructure architectures.

About the authors
Default avatar
Savic

author



Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more