Due to the way terraform modules work, all outputs from a module that an user require in the invocation app, will require to create outputs for the corresponding ones from the module output.
I understand it's a tf quirk, and allows for some separation and renaming of outputs vars if require .
But it also cause huge duplication of code and keep it in think
It would be really appreciate if there was an easy was to push modules outputs to the state file
Thanks in advance
+1 Is there an easier way to handle passing output up from modules? Otherwise I end up replicating lots of boiler plate code like this:
output "rds-sg" {
value = "${module.security.rds-sg}"
}
output "bastion-sg" {
value = "${module.security.bastion-sg}"
}
output "frontend-servers-sg" {
value = "${module.security.frontend-servers-sg}"
}
I absolutely think this would be superbly useful. However, I can see situations where TOO MUCH info comes out, so possibly rather than it being a default, it could be a choice, reducing all your boilerplate to
something like:
```
output "all_vars" {
all_values = true
}
A "module by module" boolean would probably work better in that case... ie yes for module.vpc, no for module.rds or similar.
I guess the entity that is calling the module could have a flag to export the outputs?
Is this something that have enough granularity for you guys ?
I would think a boolean in the outputs that you want to be passed on, e.g
output "private_ip" {
value = "${resource.value.here}"
expose = true
}
combined with a map in the user e.g. exposed_outputs that can then be an output itself or just used to pick the values we want might be a nice way to go about this. Or it could be like data. and module. "categories; so usable like output.private_ip.value for example.
Hi all! Thanks for the great discussion here.
In the next major version of Terraform it'll be possible for an output to return an object value containing all of the outputs of a particular module as attributes:
output "database" {
value = module.database
}
If this output were in a child module named "example" then _its_ caller would then be able to access all of the outputs of this grandchild module using an expression like module.example.security_group_id (assuming that this "database" module has a security_group_id output value defined.)
This approach will (incidentally) also work for resource instances, so an output can export directly a resource instance as an object, without needing to pass out each of its attributes one by one.
Both of these should of course be used with care, since blindly exporting large objects up to the root module is likely to cause more coupling between modules that could be harder to maintain in the long run, but we're adding these features to give users more flexibility in how they choose to decompose their systems into modules.
This isn't exactly the same as what you've all been discussing here, since it will keep the values from each module grouped together as an object rather than "flattening" them out into individual output values, but we'd like to see what patterns can develop around this capability first to see if any further shorthand syntax is warranted, keeping in mind that each new language feature is a language complexity tradeoff.
Hi all! Sorry for the long silence here.
The feature I mentioned above has since been merged into master and included in the v0.12.0-alpha1 preview release.
To verify this, I created a child module with the following content:
output "foo" {
value = "FOO"
}
output "bar" {
value = "BAR"
}
output "baz" {
value = "BAZ"
}
...and then called it from a test root module with the following configuration:
module "child" {
source = "./child"
}
output "child_outputs" {
value = module.child
}
I was then able to apply this to see this root output aggregate all of the output values from the child module as an object:
$ terraform apply
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
child_outputs = {
"bar" = "BAR"
"baz" = "BAZ"
"foo" = "FOO"
}
As I mentioned in my earlier comment, this mechanism to get a single object value representing all of the outputs of a module together is how we intend to address the use-case covered by this issue. This is a compromise to keep all of the output declarations explicit while still allow complex results to be returned.
Since this feature is merged, I'm going to close this out. It'll also be included in the forthcoming v0.12.0 final release. Thanks again for the discussion here, and thanks for your patience while we laid the groundwork to make this possible.
I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
Most helpful comment
Hi all! Sorry for the long silence here.
The feature I mentioned above has since been merged into master and included in the v0.12.0-alpha1 preview release.
To verify this, I created a child module with the following content:
...and then called it from a test root module with the following configuration:
I was then able to apply this to see this root output aggregate all of the output values from the child module as an object:
As I mentioned in my earlier comment, this mechanism to get a single object value representing all of the outputs of a module together is how we intend to address the use-case covered by this issue. This is a compromise to keep all of the output declarations explicit while still allow complex results to be returned.
Since this feature is merged, I'm going to close this out. It'll also be included in the forthcoming v0.12.0 final release. Thanks again for the discussion here, and thanks for your patience while we laid the groundwork to make this possible.