Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my Terraform output not working in module?

Tags:

terraform

I have the following simple setup:

~$ tree
.
├── main.tf
└── modules
    └── world
        └── main.tf
~$ cat main.tf
output "root_module_says" {
    value = "hello from root module"
}
module "world" {
    source = "modules/world"
}
~$ cat modules/world/main.tf
output "world_module_says" {
    value = "hello from world module"
}

I then run:

~$ terraform get
~$ terraform apply

I expect to see world_module_says in the outputs, but I do not, I only see root_module_says. This is really confusing as to why?

If it helps:

~$ terraform --version
v0.10.8
like image 889
GDev Avatar asked Sep 25 '18 17:09

GDev


People also ask

How do I get the output from a module in Terraform?

From the virtual machine module, create an output for the IP address, then use the IP address as an input value for the firewall child module. Below is an example of adding an output value to a Terraform configuration. Use the output keyword followed by an identifier for the output.

How do I access Terraform output?

Terraform Output Command To get the raw value without quotes, use the -raw flag. To get the JSON-formatted output, we can use the -json flag. This is quite useful when we want to pass the outputs to other tools for automation since JSON is way easier to handle programmatically.

How does output work in Terraform?

Terraform output values allow you to export structured data about your resources. You can use this data to configure other parts of your infrastructure with automation tools, or as a data source for another Terraform workspace. Outputs are also necessary to share data from a child module to your root module.

How do you call a output variable in Terraform?

Using a variable A variable's value can be accessed from within the terraform module block by using var. <variable_name> . Below we have an example demonstrating this. The variable's value can only be accessed in an expression within the modules where it was declared.


3 Answers

Terraform only shows the output from root (by default pre v0.12) https://www.terraform.io/docs/commands/output.html

Prior to Terraform 0.12 you can get the output from the world module with:

terraform output -module=world

I think the logic here is that the output from the module would be consumed by root and if you actually needed the output then you'd output it in root too so main.tf might contain this:

output "root_module_says" {
    value = "hello from root module"
}
output "world_module_says" {
    value = "${module.world.world_module_says}"
}
module "world" {
    source = "modules/world"
}

Beginning with Terraform 0.12 this is the only way to get the output from within a module.

like image 29
9bO3av5fw5 Avatar answered Oct 22 '22 19:10

9bO3av5fw5


Before Terraform 0.12

  • The below command shows the output for a specific module

    terraform output -module=example_module
    

After Terraform 0.12

  1. The below command fails in Terraform 0.12 and above with an error:

    terraform output -module=example_module
    
    Error: Unsupported option
    
    The -module option is no longer supported since Terraform 0.12, because now
    only root outputs are persisted in the state.
    
  2. To get outputs from a module in Terraform 0.12 and above, you must export them from the root (e.g example_module) module using an output block in the caller module.

    This can be now done simply by adding one line in the caller module like below:

    output "example_module_outputs" {
      value = module.example_module
    }
    
  3. Now you can see the output running the following command:
    terraform output
    
like image 145
Amit Yadav Avatar answered Oct 22 '22 17:10

Amit Yadav


Expansion to the answers above when using multiple output varialbes:

When accessing a module output group (using the 'terraform output' command from a console or a script) then Terraform will printout all output variables within this group in a formatted way, or in json format using '-json' flag.

When extracting output values, we can use the '-raw' flag only if there is a single variable which has a string format.

If we have more than 1 outout in the output group within the module:

Lets say we declared in the 'root' module the following outout group in a module:

    output "world_world_module_says" {
      value = module.world.world_module_says
    }

and in the module main.tf we have 2 vars:

    output "world_module_says" {
        value = "hello from world module"
    }
    output "world_module_says_again" {
        value = "hi again from world module"
    }

Two ways to extract a single output variable from the group:

  1. using -json flag and manipulating the output using the jq command:
    terraform output -json world_world_module_says |jq '.'"world_module_says" 
  1. The other way is to declare each output individually in the 'root' module to allow easy access using '-raw':
    output "world_world_module_says" {
      value = module.world.world_module_says
    }
    output "world_world_module_says_again" {
      value = module.world.world_module_says_again
    }
like image 4
Yossi Schwartz Avatar answered Oct 22 '22 18:10

Yossi Schwartz