-
Notifications
You must be signed in to change notification settings - Fork 9.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
core: fix the provisioner graphing #4877
Conversation
Without this change, all provisioners are added to the graph by default and they are never pruned from the graph if their not needed.
Hi @svanharmelen, this seems reasonable at first glance! I'm curious, though, does this have any functional effect? Also same question for the |
@phinze I was still typing the complete description for this PR, so please have another look as I suspect it will now answer your questions 😉 /CC @mitchellh as this is mainly code he wrote at the time... |
@phinze @mitchellh any feedback or thoughts about this one? |
Any chance we can discuss this one? If it's up to me I would just remove The reordering I did in this PR still feel hacky. So would the suggested code change do the trick and be robust enough? Or should we extend that peace of code to check additional use cases/types? |
Looking now, expect a follow up comment shortly. |
My thoughts are: not having the missing and prune transformers make sense. If we can remove those without breaking any tests (other than those that might just test for their existence), then it probably will work fine. In terms of this PR, lets go with the route that makes the code simpler vs more complex, if we can do that while having all tests still pass. |
Thanks for the feedback! I'll update the PR (somewhere tomorrow) accordingly 👍 |
@phinze @mitchellh just tried to remove the I first added a few lines of code to the To make things a little more descriptive I renamed a few types that had So I think the PR should be good to go now, however I do have one feedback question left... I noticed I had to change 1 test in order to make all tests pass: https://github.com/hashicorp/terraform/pull/4877/files#diff-1848efa7a9473a60ae890ae47d35cbf0 I looked at this one, but I fail to fully understand if the previous version is the correct and desired outcome or if this current version is in fact the expected outcome. I was unable to reason about it correctly, so I hope one of you can enlighten me on this one. Thanks! |
// Add our own missing provider node to the graph | ||
m[p] = g.Add(&graphNodeMissingProvider{ProviderNameValue: p}) | ||
// Add the missing provider node to the graph | ||
m[p] = g.Add(&graphNodeProvider{ProviderNameValue: p}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why rename this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm actually +1 on this rename or something similar (since this node really does represent the provider itself in the graph) but I'd prefer we do it as a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that was exactly the argument for renaming this... Since this node represents the provider itself in the graph, this name seemed a little more suitable and more descriptive.
I added the rename in this PR as the provisioner and provider transformers are very much inline with each other and I changed it for the provisioner as well.
But I'll take this code out if you prefer that and make a new PR for the provider renaming... 👍
One question about why renaming the missing provider when I believe this PR is about provisioners. |
Check... Replied inline, but will take out the provider rename and put in it a separate PR. |
And renamed some types so they better reflect what they are for.
Updated the PR so it only contains provisioner related changes... Still would like to get a conformation (double check) that the updated test case is now giving the expected results so we're sure to not introduce any kind of regression. Thx! |
@svanharmelen I thought you were pulling out the renames from this branch? do you still need to push those changes? |
ah, all the functional changes are in the first commit. LGTM, though I'm not qualified to vouch for test completeness. |
Hello again! This is looking good - I believe it solves the |
Sounds good... Thx! |
Currently failing, but going to move this commit around to vet fixes. Confirmed that #4877 fixes the provisioner half of this!
Okay just confirmed on the linked branch/commit that this does indeed address the provisioner side of that problem. So I'll merge this now and then land that test once the Provider side of the issue is handled (looking into that now). Thanks for all your work on this, Sander! 👍 |
core: fix the provisioner graphing
Context: As part of building up a Plan, Terraform needs to detect "orphaned" resources--resources which are present in the state but not in the config. This happens when config for those resources is removed by the user, making it Terraform's responsibility to destroy them. Both state and config are organized by Module into a logical tree, so the process of finding orphans involves checking for orphaned Resources in the current module and for orphaned Modules, which themselves will have all their Resources marked as orphans. Bug: In #3114 a problem was exposed where, given a module tree that looked like this: ``` root | +-- parent (empty, except for sub-modules) | +-- child1 (1 resource) | +-- child2 (1 resource) ``` If `parent` was removed, a bunch of error messages would occur during the plan. The root cause of this was duplicate orphans appearing for the resources in child1 and child2. Fix: This turned out to be a bug in orphaned module detection. When looking for deeply nested orphaned modules, root.parent was getting added twice as an orphaned module to the graph. Here, we add an additional check to prevent a double add, which addresses this scenario properly. Fixes #3114 (the Provisioner side of it was fixed in #4877)
Thanks! |
Context: As part of building up a Plan, Terraform needs to detect "orphaned" resources--resources which are present in the state but not in the config. This happens when config for those resources is removed by the user, making it Terraform's responsibility to destroy them. Both state and config are organized by Module into a logical tree, so the process of finding orphans involves checking for orphaned Resources in the current module and for orphaned Modules, which themselves will have all their Resources marked as orphans. Bug: In #3114 a problem was exposed where, given a module tree that looked like this: ``` root | +-- parent (empty, except for sub-modules) | +-- child1 (1 resource) | +-- child2 (1 resource) ``` If `parent` was removed, a bunch of error messages would occur during the plan. The root cause of this was duplicate orphans appearing for the resources in child1 and child2. Fix: This turned out to be a bug in orphaned module detection. When looking for deeply nested orphaned modules, root.parent was getting added twice as an orphaned module to the graph. Here, we add an additional check to prevent a double add, which addresses this scenario properly. Fixes #3114 (the Provisioner side of it was fixed in #4877)
Context: As part of building up a Plan, Terraform needs to detect "orphaned" resources--resources which are present in the state but not in the config. This happens when config for those resources is removed by the user, making it Terraform's responsibility to destroy them. Both state and config are organized by Module into a logical tree, so the process of finding orphans involves checking for orphaned Resources in the current module and for orphaned Modules, which themselves will have all their Resources marked as orphans. Bug: In hashicorp#3114 a problem was exposed where, given a module tree that looked like this: ``` root | +-- parent (empty, except for sub-modules) | +-- child1 (1 resource) | +-- child2 (1 resource) ``` If `parent` was removed, a bunch of error messages would occur during the plan. The root cause of this was duplicate orphans appearing for the resources in child1 and child2. Fix: This turned out to be a bug in orphaned module detection. When looking for deeply nested orphaned modules, root.parent was getting added twice as an orphaned module to the graph. Here, we add an additional check to prevent a double add, which addresses this scenario properly. Fixes hashicorp#3114 (the Provisioner side of it was fixed in hashicorp#4877)
Context: As part of building up a Plan, Terraform needs to detect "orphaned" resources--resources which are present in the state but not in the config. This happens when config for those resources is removed by the user, making it Terraform's responsibility to destroy them. Both state and config are organized by Module into a logical tree, so the process of finding orphans involves checking for orphaned Resources in the current module and for orphaned Modules, which themselves will have all their Resources marked as orphans. Bug: In hashicorp#3114 a problem was exposed where, given a module tree that looked like this: ``` root | +-- parent (empty, except for sub-modules) | +-- child1 (1 resource) | +-- child2 (1 resource) ``` If `parent` was removed, a bunch of error messages would occur during the plan. The root cause of this was duplicate orphans appearing for the resources in child1 and child2. Fix: This turned out to be a bug in orphaned module detection. When looking for deeply nested orphaned modules, root.parent was getting added twice as an orphaned module to the graph. Here, we add an additional check to prevent a double add, which addresses this scenario properly. Fixes hashicorp#3114 (the Provisioner side of it was fixed in hashicorp#4877)
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. |
Without this change, all provisioners are added to the graph by default and they are never pruned from the graph if their not needed.
I must admit I'm not a 100% sure if this is the correct solution, but there are a few (weird) things that we should discuss and/or have a look at in order to determine the correct solution.
MissingProvisionerTransformer
? It makes sense to have aMissingProviderTransformer
because you could have used a resource without specifying the neededprovider
for that resource. But that isn't possible for aprovisioner
as that is a single entity which you either specify in your config, or you don't. So how can you ever have a missingprovisioner
in your config?PruneProvisionerTransformer
. What could this transformer ever prune (if we don't add all availableprovisioners
or selves that is, see point 3 😉).MissingProvisionerTransformer
, then I suppose we only want to add theprovisioners
that we actually need. Currently we just add all knownprovisioners
and try to prune them in a later stage (which currently doesn't work, see point 4). The code in the PR changes the logic by only adding theprovisioners
that are needed by the supplied config in the same way as this is done forproviders
.PruneProviderTransformer
andPruneProvisionerTransformer
. They currently both check if there are anyUpEdges
, and only if there none theprovider
orprovisioner
is removed from the graph. But when theRootTransformer
is executed before one of the prune transformers, they will have at least 1UpEdge
, being thegraphNodeRoot
added by theRootTransformer
. And since the current graph builder ordering places theRootTransformer
before the prune transformers, it means the prune transformers are effectively broken at this moment.The code in this PR fixes the problem described in point 4 by reordering the transformers, but that doesn't feel like a robust solution. Another (possibly better) fix would be to change this code to something like:
This would make the ordering of the graph transformations less critical, but I'm not sure if this is a 100% fix and if this also works when your using modules and/or already have a root, not being a
graphNodeRoot
(not sure that is even possible?). So I need some input to be sure this would indeed be a solid fix for the current prune transformers problem in all use cases...I labeled this as a bug, because the current code allocates resources (mainly a goroutine with a yamux stream) for each
provisioner
for every action (e.g.refresh
,plan
,apply
) which is never released. If your running Terraform as a long running daemon (API) you can see this will kill your service at a certain point in time 😁