Skip to main content

Terraform Output Formats

Introduction

When working with Terraform, outputs provide a way to extract and display information about your infrastructure. However, simply displaying raw output values isn't always ideal - especially when dealing with complex data structures or when you need to integrate Terraform with other tools in your workflow. This is where Terraform output formats come into play.

In this tutorial, we'll explore different ways to format and customize your Terraform outputs to enhance readability and improve integration capabilities.

Basic Output Syntax Refresher

Before diving into formatting options, let's quickly review the basic syntax for defining outputs in Terraform:

hcl
output "instance_ip" {
value = aws_instance.example.public_ip
description = "The public IP address of the web server"
}

When you run terraform apply, outputs appear as:

Outputs:

instance_ip = "203.0.113.10"

Output Format Options

Terraform provides several ways to format your outputs depending on your needs.

1. String Formatting

You can use Terraform's string interpolation to format string outputs:

hcl
output "server_details" {
value = "Server IP: ${aws_instance.example.public_ip}, Instance ID: ${aws_instance.example.id}"
}

This will produce:

Outputs:

server_details = "Server IP: 203.0.113.10, Instance ID: i-0123456789abcdef0"

2. Multi-line Strings (Heredoc)

For outputs that contain multiple lines, you can use Terraform's heredoc syntax:

hcl
output "connection_details" {
value = <<EOT
Server IP: ${aws_instance.example.public_ip}
SSH Command: ssh admin@${aws_instance.example.public_ip}
Web URL: http://${aws_instance.example.public_ip}:8080
Instance ID: ${aws_instance.example.id}
EOT
}

Output:

Outputs:

connection_details = <<EOT
Server IP: 203.0.113.10
SSH Command: ssh [email protected]
Web URL: http://203.0.113.10:8080
Instance ID: i-0123456789abcdef0
EOT

3. Formatted JSON Output

For complex data structures, Terraform can format your outputs as JSON:

hcl
output "instance_details" {
value = {
id = aws_instance.example.id
ip = aws_instance.example.public_ip
subnet = aws_instance.example.subnet_id
security_groups = aws_instance.example.security_groups
}
}

When you run terraform output -json, you'll get:

json
{
"instance_details": {
"sensitive": false,
"type": [
"object",
{
"id": "string",
"ip": "string",
"security_groups": [
"list",
"string"
],
"subnet": "string"
}
],
"value": {
"id": "i-0123456789abcdef0",
"ip": "203.0.113.10",
"security_groups": [
"sg-0123456789abcdef0"
],
"subnet": "subnet-0123456789abcdef0"
}
}
}

Special Output Format Commands

Terraform provides special command-line options for formatting outputs:

1. Raw Output Format

To retrieve just the value of a specific output without any formatting:

bash
terraform output instance_ip

Result:

203.0.113.10

2. JSON Output Format

To get all outputs in JSON format:

bash
terraform output -json

Result:

json
{
"instance_ip": {
"sensitive": false,
"type": "string",
"value": "203.0.113.10"
},
"server_details": {
"sensitive": false,
"type": "string",
"value": "Server IP: 203.0.113.10, Instance ID: i-0123456789abcdef0"
}
}

To get a specific output in JSON format:

bash
terraform output -json instance_ip

Result:

json
"203.0.113.10"

Practical Use Cases

Let's explore some real-world applications of Terraform output formatting:

1. Integration with Shell Scripts

hcl
output "instance_ips" {
value = join(",", aws_instance.cluster[*].public_ip)
description = "Comma-separated list of instance IPs"
}

This output can be easily consumed in a shell script:

bash
#!/bin/bash
IPS=$(terraform output -raw instance_ips)
for IP in ${IPS//,/ }; do
echo "Connecting to $IP..."
ssh -i key.pem admin@$IP "sudo apt update"
done

2. Generating Configuration Files

hcl
output "nginx_config" {
value = <<-EOT
server {
listen 80;
server_name ${var.domain_name};

location / {
proxy_pass http://${aws_instance.app.private_ip}:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
EOT
}

You can save this to a file:

bash
terraform output -raw nginx_config > /etc/nginx/sites-available/my-app.conf

3. Creating an Ansible Inventory

hcl
output "ansible_inventory" {
value = <<-EOT
[webservers]
%{for ip in aws_instance.web[*].public_ip~}
web-${index(aws_instance.web[*].public_ip, ip)} ansible_host=${ip}
%{endfor~}

[databases]
%{for ip in aws_instance.db[*].public_ip~}
db-${index(aws_instance.db[*].public_ip, ip)} ansible_host=${ip}
%{endfor~}
EOT
}

4. Visualization with Mermaid Diagrams

Using Terraform outputs to generate a diagram of your infrastructure:

hcl
output "infrastructure_diagram" {
value = <<-EOT
```mermaid
graph TD
VPC["VPC: ${aws_vpc.main.id}"] --> Subnet1["Public Subnet: ${aws_subnet.public.id}"]
VPC --> Subnet2["Private Subnet: ${aws_subnet.private.id}"]
Subnet1 --> WebServer["Web Server: ${aws_instance.web.id}"]
Subnet2 --> Database["Database: ${aws_instance.db.id}"]
Internet((Internet)) --> LB["Load Balancer: ${aws_lb.frontend.name}"]
LB --> WebServer

EOT }


## Advanced Output Formatting

### 1. Conditional Outputs

You can conditionally format outputs based on certain conditions:

```hcl
output "connection_info" {
value = var.environment == "production" ? (
"Connect using the production endpoints at https://${aws_instance.prod.public_ip}"
) : (
"Connect using the development endpoint at http://${aws_instance.dev.public_ip}:8080"
)
}

2. Custom Formatting with Functions

Terraform provides numerous functions to help format output data:

hcl
output "instance_summary" {
value = [
for i, instance in aws_instance.cluster : {
index = i
name = instance.tags.Name
ip = instance.public_ip
type = instance.instance_type
az = instance.availability_zone
}
]
}

output "table_format" {
value = join("
", [
"| Index | Name | IP | Type | AZ |",
"|-------|------|----|----|---|",
for i, inst in aws_instance.cluster :
"| ${i} | ${inst.tags.Name} | ${inst.public_ip} | ${inst.instance_type} | ${inst.availability_zone} |"
])
}

3. Using templatefile for Complex Formatting

For complex formatting, you can use the templatefile function:

hcl
output "readme_content" {
value = templatefile("${path.module}/templates/readme.tpl", {
instances = aws_instance.cluster
vpc_id = aws_vpc.main.id
region = var.region
env = var.environment
})
}

With a template file (templates/readme.tpl):

markdown
# Infrastructure Documentation

## Environment: ${env}
## Region: ${region}
## VPC ID: ${vpc_id}

## Instances:

| Name | IP Address | Instance Type | AZ |
|------|------------|--------------|-----|
%{ for instance in instances ~}
| ${instance.tags.Name} | ${instance.public_ip} | ${instance.instance_type} | ${instance.availability_zone} |
%{ endfor ~}

Exporting and Using Terraform Outputs

Here are some common ways to export and use Terraform outputs:

1. Storing Outputs in a File

bash
# Export all outputs to JSON
terraform output -json > terraform_outputs.json

# Export specific output
terraform output -raw instance_ids > instance_ids.txt

2. Using Outputs in CI/CD Pipelines

yaml
# Example GitLab CI step
deploy_app:
stage: deploy
script:
- export DB_HOST=$(terraform output -raw db_host)
- export DB_PORT=$(terraform output -raw db_port)
- deploy-script.sh --db-host=$DB_HOST --db-port=$DB_PORT

3. Using Outputs Across Terraform Projects

You can also use outputs from one Terraform project in another using data sources:

hcl
# In your dependent Terraform project
data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = "terraform-state"
key = "network/terraform.tfstate"
region = "us-west-2"
}
}

resource "aws_instance" "app" {
# Use the VPC ID output from the network project
vpc_security_group_ids = [data.terraform_remote_state.network.outputs.security_group_id]
subnet_id = data.terraform_remote_state.network.outputs.subnet_id
# ... other configuration
}

Summary

Terraform output formats provide powerful ways to present infrastructure information in a readable and usable manner. By leveraging different formatting options, you can:

  • Improve readability with string formatting and heredoc syntax
  • Structure complex data with JSON outputs
  • Create integration points for other tools and scripts
  • Generate configuration files and documentation automatically
  • Visualize your infrastructure

These formatting capabilities are essential when working with larger infrastructure projects and when integrating Terraform into broader DevOps workflows.

Additional Resources

  • Practice customizing outputs for different scenarios
  • Try creating outputs that can be directly used by other tools
  • Experiment with generating visual documentation using the output data

By mastering Terraform output formats, you'll be able to create more user-friendly infrastructure code and streamline your DevOps processes.



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)