How to use Terraform output values?



In this article we are going to look on terraform output values. Terraform output values will be really useful when you want to debug your terraform code. Terraform output values can help you to print the attributes reference(arn, instance_state, outpost_arn, public_ip, public_dns etc) on your console.

The typical syntax of Terraform output values is -

How to use terraform output locals?

Once you run your terraform apply command, it is going to print Hello this is output onto your console.

But there are more than just simply outputting static text values with terraform output variables. You can do a lot more.

Table of Content

  1. How to print the public_ip of aws_instance?
  2. How to create output.tf for terraform output values?
  3. How to prevent printing sensitive info on the console?
  4. Various use cases of output variables
  5. How do you output multiple values in Terraform?
  6. How to access the output variable in Terraform module?
  7. Explain terraform output command with example and how it is different from output variable?
  8. How to use Terraform output for resource with count?
  9. How to display sensitive inside output block using Terraform nonsensitive function?
  10. Conclusion



1. How to print the public_ip of aws_instance?

This is one of the most classic examples for terraform output values. As we know terraform is used as Infrastructure as code, so with the help of terraform you can provision many resources such - aws_instances, aws_vpc etc.

But is there a way by which you can know the public_ip address of the instance which you are planning to provision using terraform?

Yes, there is a really convenient and easy way to achieve that.

Here is my aws_instance which I have defined as inside my main.tf -

 1provider "aws" {
 2   region     = "eu-central-1"
 3   access_key = <YOUR_ACCESS_KEY>
 4   secret_key = <YOUR_SECRET_KEY>
 5}
 6
 7resource "aws_instance" "ec2_example" {
 8   
 9   ami           = "ami-0767046d1677be5a0"
10   instance_type = "t2.micro"
11   subnet_id = aws_subnet.staging-subnet.id
12   
13   tags = {
14           Name = "test - Terraform EC2"
15   }
16}

You can simply append following terraform output value code inside your main.tf file so that it can print the public ip of your aws_instance

1output "my_console_output" {
2  value = aws_instance.ec2_example.public_ip
3} 

Break down of the above script

  1. aws_instance - It is the keyword which you need write as is.
  2. ec2_example - The name which we have given at the time of creating aws_instance
  3. public_ip - You can use attributes reference page to get all the attribute which you want to print on console.

The same approach can be followed to print - arn,instance_state,outpost_arn, password_data, primary_network_interface_id, private_dns, public_dns etc.



2. How to create output.tf for terraform output values?

In the previous point we have seen how to create your first terraform output values. But if you have noticed we have created the terraform output values inside the same main.tffile.

It is completely okay to create terraform output values inside the main.tf but this practice is certainly not recommended in the industry.

The recommended way is to create a separate output.tf specially of the terraform output values, so that all the output values can be stored there.

The only change which you need to do over here is to create a new output.tf and store the following terraform code init -

output.tf

1output "my_console_output" {
2  value = aws_instance.ec2_example.public_ip
3} 

Your directory structure should look like this -

How to use terraform output locals?



3. How to prevent printing sensitive info on the console?

As terraform output values help us to print the attributes reference values but sometimes you can not print all the values on console.

So to prevent from printing sensitive values on the console you need to set sensitive = true.

Here is an example of the terraform code where we want to prevent showing the public ip to console -

1output "my_console_output" {
2  value = aws_instance.ec2_example.public_ip
3  sensitive = true
4} 

In the above code if you noticed we are using sensitive = true which tells terraform not to show public ip on console.



4. Various use cases of output variables

Here are some common use cases for Terraform output variables include:

  1. Print IP address of a load balancer - Exposing the IP address of a load balancer to be used by other parts of the infrastructure for routing traffic.
 1#main.tf 
 2
 3resource "aws_elb" "example" {
 4  name               = "example"
 5  internal           = true
 6  security_groups    = [aws_security_group.example.id]
 7  listener {
 8    instance_port     = 80
 9    instance_protocol = "http"
10    lb_port           = 80
11    lb_protocol       = "http"
12  }
13}
14
15#The following output variable will print the IP address of loadbalancer
16output "elb_dns_name" {
17  value = aws_elb.example.dns_name
18}
19 
  1. Print DNS name of Database - Exposing the DNS name of a database to be used by other parts of the infrastructure for connecting to the database.
 1#main.tf
 2
 3resource "aws_rds_cluster" "example" {
 4  cluster_identifier = "example"
 5  master_username    = "example"
 6  master_password    = "example"
 7  db_subnet_group_name = aws_db_subnet_group.example.name
 8}
 9
10#The following output variable will print the DNS name of AWS RDS cluster
11output "rds_cluster_endpoint" {
12  value = aws_rds_cluster.example.endpoint
13} 
  1. Get the URL of static website deployed on AWS- If you have ever deployed an static website on S3 bucket then you can print the website_endpoint using the output variables in terraform -
 1#main.tf
 2
 3resource "aws_s3_bucket" "example" {
 4  bucket = "example-bucket"
 5  acl    = "public-read"
 6  website {
 7    index_document = "index.html"
 8  }
 9}
10
11# The following output block will print the URL of static website deployed on S3 Bucket
12output "website_url" {
13  value = aws_s3_bucket.example.website_endpoint
14} 
  1. Exporting the ARN of an AWS IAM role - Exporting the ARN of an AWS IAM role to be used by other parts of the infrastructure for granting permissions.
 1#main.tf
 2
 3resource "aws_iam_role" "example" {
 4  name = "example"
 5
 6  assume_role_policy = <<EOF
 7{
 8  "Version": "2012-10-17",
 9  "Statement": [
10    {
11      "Effect": "Allow",
12      "Principal": {
13        "Service": "ec2.amazonaws.com"
14      },
15      "Action": "sts:AssumeRole"
16    }
17  ]
18}
19EOF
20}
21
22#print the arn using the output variable
23output "role_arn" {
24  value = aws_iam_role.example.arn
25} 

Note - Click here to read more on How to manage AWS IAM user, Roles and Policies with Terraform


5. How do you output multiple values in Terraform?

In Terraform, you can output multiple values by defining multiple output blocks in your configuration. Each output block should have a unique name and a corresponding value.

For example, you could output both the public and private IP addresses of an EC2 instance like this:

 1resource "aws_instance" "example" {
 2  ami           = "ami-0ff8a91507f77f867"
 3  instance_type = "t2.micro"
 4}
 5
 6# Output-1
 7output "public_ip" {
 8  value = aws_instance.example.public_ip
 9}
10
11#Output-2
12output "private_ip" {
13  value = aws_instance.example.private_ip
14} 

Using Map Function- You can also output multiple values in a single output block by using the map function.

1output "instance_ips" {
2  value = {
3    public_ip  = aws_instance.example.public_ip
4    private_ip = aws_instance.example.private_ip
5  }
6} 

Using join function- You can also output multiple attributes from a resource using join function

1output "security_groups" {
2  value = join(",",aws_instance.example.*.security_groups)
3} 

6. How to access the output variable in Terraform module?

In Terraform, you can access output variables defined in a module by using the module or module.name syntax, where name is the name of the module. For example, if you have a module named "example" with an output variable named "output_var", you can access it in the root module like this:

1module "example" {
2  source = "path/to/module"
3  # ... other module inputs
4}
5
6#output from module
7output "example_output" {
8  value = module.example.output_var
9}

You can also use the output variables in other resources or modules in the same way. For example, if you have another module that needs to use the output of the example module, you can reference it like this:

1module "example2" {
2  source = "path/to/module2"
3  example_output = module.example.output_var
4  # ... other module inputs
5} 

Alternatively, you can use the output block in the child module and then reference it in the root module by using the module and module.name syntax.

1module "example" {
2  source = "path/to/module"
3  # ... other module inputs
4}
5
6output "example_output" {
7  value = module.example.output_var
8}

7. Explain terraform output command with example and how it is different from output variable?

The output command is used to display the values of output variables defined in the configuration. It can be used to show the values of output variables after a successful terraform apply command has been run.

The syntax of the output command is:

1terraform output [options] [NAME] 

Where NAME is the name of the output variable that you want to display. If you don't specify a NAME, it will display all the output variables defined in your configuration.

For example, consider the following configuration:

 1resource "aws_instance" "example" {
 2  ami           = "ami-0ff8a91507f77f867"
 3  instance_type = "t2.micro"
 4}
 5
 6output "public_ip" {
 7  value = aws_instance.example.public_ip
 8}
 9
10output "private_ip" {
11  value = aws_instance.example.private_ip
12} 

After running terraform apply, you can display the value of the public_ip output variable by running the command terraform output public_ip which will output something like this:

1public_ip = xx.xxx.xxx.xxx 

Similarly, you can display the value of the private_ip output variable by running the command terraform output private_ip which will output something like this:

1private_ip = xxx.xxx.xxx.xxx 

On the other hand, the output variable is a block defined in the Terraform configuration file, it allows you to extract information from the state file and make it available for use elsewhere in the same configuration file.

The output command is used to display the values of output variables that have been defined in the configuration, it does not change anything in the infrastructure, but it shows the current state of the output variables defined in the configuration file.


8. How to use Terraform output for resource with count?

There are certain situation where you need to use terraform output for multiple resources using the count. But to achieve this you do not need to loop inside the terraform output block.

Here is an example in which I have created the 3 EC2 Instances on AWS with terraform and I am using only single output block to print all the three public DNS info of the EC2 instances -

1#Following resource block will create 3 EC2 instances
2resource "aws_instance" "ec2_example" {
3  count = 3
4  ami = "ami-0767046d1677be5a0"
5  instance_type = "t2.micro"
6  tags = {
7    Name = "test-t2-micro"
8  }
9}

Output Block to fetch all the three public DNS

1 output "fetched_info_from_aws" {
2  value = ["${aws_instance.ec2_example.*.public_dns}"]
3}

Here is the screenshot of the output which is generated -

1fetched_info_from_aws = [
2  [
3    "ec2-3-70-132-62.eu-central-1.compute.amazonaws.com",
4    "ec2-3-76-218-65.eu-central-1.compute.amazonaws.com",
5    "ec2-18-193-116-124.eu-central-1.compute.amazonaws.com",
6  ],
7]

Terraform output for resource with count


9. How to display sensitive inside output block using Terraform nonsensitive function?

In Terraform, the nonsensitive function can be used to mark an output variable as sensitive, which means that its value will be obscured in the output of the terraform output command. This can be useful for sensitive information like passwords or private keys.

The nonsensitive function can be used to mark an output variable as non-sensitive, which means that its value will be displayed in plain text in the output of the terraform output command.

Here is an example of how you might use the nonsensitive function to mark an output variable as non-sensitive:

1resource "aws_iam_access_key" "example" {
2  user = aws_iam_user.example.name
3}
4
5output "access_key" {
6  value = nonsensitive(aws_iam_access_key.example.id)
7}

In the above example, the aws_iam_access_key resource is being created and the output variable access_key is being set to the ID of the access key, but the nonsensitive function is used to mark the output variable as non-sensitive.

Conclusion

Hope the above article will help you to build your understanding on terraform output values.

With the combination of terraform variable, terraform locals you really benefit well on terraform output values

You can read more on terraform output values over here




Read More - Terragrunt -

  1. How to use Terragrunt?

Posts in this Series