Open dmattia opened 4 years ago
That's a fair point. This happens because getting the output calls RunTerragrunt
here, and that function is currently parsing the target config in full.
The implementation to fix this is a bit involved though because it means we need to update the RunTerragrunt
routine to do "just-in-time" config parsing. That is, it needs to index all the terraform commands and construct a mapping so that it only parses the relevant pieces of the config for each command. E.g., output
may only need the terraform
block, while apply
needs all the inputs
, unless it has a plan file (you can see how this can get complicated).
Note that we can't just parse out the terraform
block for calling output
and be done with it. The crux of the issue is parsing out the dependency
blocks from the target config, and avoiding that requires an update to the configuration parsing mechanism. Right now, we parse dependency
blocks before terraform
blocks (see https://terragrunt.gruntwork.io/docs/getting-started/configuration/#configuration-parsing-order) because we want to support the usage of dependency
in setting hooks
and extra_arguments
and the like. Updating that means we need some kind graph based parsing mechanism so that we only parse dependency
blocks if it is used: a very involved refactor!
I'd be willing to overhaul the configuration parsing mechanism, but right now we are buried with other initiatives to take on this. If anyone else in the community wants to take a crack at this, please submit an RFC detailing the approach given the changes involved.
Awesome, thanks for the write up @yorinasub17! I won't be able to work on an RFC in the near future, but will keep this in my back log just in case I ever have time.
I came up with a potential intermediate solution that I hope will cover 80% of use cases. Check out the PR description for more info: https://github.com/gruntwork-io/terragrunt/pull/1311
I think that is an excellent solution!
The intermediate optimization is now released as https://github.com/gruntwork-io/terragrunt/releases/tag/v0.23.35 (binaries will show up shortly).
Keeping this issue open as this update does not allow this optimization for all use cases. In particular, we've been directing folks to start using generate
blocks to manage state backends that are not s3
or gcs
, which means those folks won't benefit from the optimization.
Will keep this ticket open until we can support generate
block based backend configuration.
Just tested it out and it's working wonderfully!
Pictured is a module with ~100 nested dependencies, but only the 11 declared dependencies that you see in the output before the state lock is acquired 😄
When I use v0.23.34 without this optimization, you can see that there are many more dependencies:
The total time to run this module is down from 2m13s to 40s, but there's probs 15ish seconds just to aquire the state lock and refresh the state, so this is extremely efficient now in my mind.
Thank you so much for all your work on this!
That's great to hear @dmattia ! Thanks for sharing!
Current behavior
If I have a module named MainModule with two dependency blocks, and those two dependencies each depend on a few other modules, and I run a
terragrunt plan
on MainModule, terragrunt will run aterraform output -json
to check the state of all modules described in this scenario, not just on the two top level dependencies.What I don't love about this
It is slower
In my real world terragrunt config, we have hundreds of modules, some of which have over a dozen dependencies, each of which have their own. Even with provider caching, I still see cases where a
terragrunt plan
takes over ten minutes because it checks all of the state in series without parallelization.It goes against my intuition of the permissions model
This one is highly opinionated, so I only mean it as a suggestion. But say I have the following modules:
Running a plan on EcsDevModule would have a deep level dependency on being able to access the Prod env state, which I do no like. Instead, I would prefer if I only had to give access to CommonsOrg state.