Bootstrap FreeKB - Terraform - Display outputs using the terraform output command
Terraform - Display outputs using the terraform output command

Updated:   |  Terraform articles

As the name implies, the terraform output command is used to return outputs. Let's say you have the following files on your Terraform server.

├── main.tf (root module)
├── data.tf
├── locals.tf
├── outputs.tf
├── providers.tf
├── terraform.tfstate
├── variables.tf
├── child (directory)
│   ├── main.tf (child module)
│   ├── data.tf
│   ├── outputs.tf
│   ├── resources.tf

 

This assumes terraform has already been initialized by the terraform init command. 

~]# terraform init
Initializing the backend...
Initializing modules...
Initializing provider plugins...
Terraform has been successfully initialized!

 

Let's say you issue the terraform output command and Warning: No outputs found is returned.

Warning: No outputs found

 

This should mean the outputs key in your terraform.tfstate file is empty.

~]$ cat terraform.tfstate
{
  "version": 4,
  "terraform_version": "1.2.6",
  "serial": 1,
  "outputs": {},

 

This can happen if the outputs.tf file in the same directory as your main root module (main.tf) is empty, has no outputs.

~]# cat outputs.tf

 

Let's say you add one or more outputs to the outputs.tf file in the same directory as your main root module (main.tf).

output "greeting" {
  value = "Hello World"
}

 

And then you issue the terraform refresh command. The outputs in the outputs.tf file in the same directory as your main root module (main.tf) should now be displayed.

~]# terraform refresh
Outputs:

greeting = "Hello World"

 

And your terraform.tfstate file should contain the outputs.

]$ cat terraform.tfstate 
{
  "version": 4,
  "terraform_version": "1.5.2",
  "serial": 1,
  "lineage": "162d2e73-f0c7-4374-e946-2ce75c65ef76",
  "outputs": {
    "greeting": {
      "value": "Hello World",
      "type": "string"
    }
  },

 


Child Modules

Let's say you want to pass outputs from a child module to the main root module. I first happened upon this when I had a root module that contained a child module (vpc in this example).

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
    }
  }
}

provider "aws" {
  access_key = var.access_key
  secret_key = var.secret_key
}

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

 

And the child module had outputs.

]$ cat vpc/outputs.tf
output "my_vpcs" {
  value = data.aws_vpc.my_vpcs
}

 

outputs must be in the root module. Thus, what I ended up doing was using a directory structure like this.

├── main.tf
├── outputs.tf
├── vpc (directory)
│   ├── vpc.tf

 

In the vpc.tf file in the child module, I used "data" to get the JSON of the VPC named my-vpc and then used "output" to store the JSON in a variable named my_vpc.

data "aws_vpc" "my-vpc" {
  filter {
    name = "tag:Name"
    values = ["my-vpc"]
  }
}

output "my_vpc" {
  value = data.aws_vpc.my-vpc
}

 

And then I had the following in outputs.tf in the same directory as my root module.

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

 

And then the terraform refresh command gave me the following.

]$ terraform refresh
module.vpc.data.aws_vpc.my_vpcs: Reading...
module.vpc.data.aws_vpc.my_vpcs: Read complete after 1s [id=vpc-014d2fcfa335d3c01]

Outputs:

vpc = {
  "arn" = "arn:aws:ec2:us-east-1:713542074252:vpc/vpc-0521ac4b76ed94d8a"
  "cidr_block" = "10.0.0.0/16"
  "cidr_block_associations" = tolist([
    {
      "association_id" = "vpc-cidr-assoc-09ff7264a51c86a4b"
      "cidr_block" = "10.0.0.0/16"
      "state" = "associated"
    },
  ])
  "default" = false
  "dhcp_options_id" = "dopt-017f0a715e4ce2fc9"
  "enable_dns_hostnames" = false
  "enable_dns_support" = true
  "filter" = toset([
    {
      "name" = "tag:Name"
      "values" = toset([
        "my-vpc",
      ])
    },
  ])
  "id" = "vpc-0521ac4b76ed94d8a"
  "instance_tenancy" = "default"
  "ipv6_association_id" = ""
  "ipv6_cidr_block" = ""
  "main_route_table_id" = "rtb-091e5416b1c0d33a6"
  "owner_id" = "713542074252"
  "state" = tostring(null)
  "tags" = tomap({
    "Name" = "my-vpc"
  })
  "timeouts" = null /* object */
}

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter 050d56 in the box below so that we can be sure you are a human.