Skip to content
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

Allow special-case evaluation of instances pending deletion. #26470

Merged
merged 8 commits into from
Oct 5, 2020

Conversation

jbardin
Copy link
Member

@jbardin jbardin commented Oct 2, 2020

Allow the evaluation of resources pending deletion in 2 special cases. We remove the ability to evaluate these resources in all other cases, simplifying the graph, and preventing deposed resources from being evaluated when involving resource using the create_before_destroy lifecycle.

During a full destroy, a provider configuration may reference data sources (and occasionally managed resources) that are going to be removed from the state. We can detect this by examining the change set for all Delete actions, and allow the evaluation of resources pending deletion to proceed. More details about the current handling of this, and the fixup transformer it used can be found in #25618.

When evaluating a destroy provisioner, we can create a limited evaluation scope that only includes the prior value of the resource and the instance key data. This bypasses the need for a special case in the global evaluator entirely. This new evaluation mode is added to lang.Scope as a new EvalSelfBlock method, which the provisioners can now switch to using as necessary.

Fixes #25631

In order to handle various edge cases during a full destroy, add
FullDestroy to the synchronized changes so we can attempt to deduce if
the plan was created from `terraform destroy`.

It's possible that the plan was created by removing all resourced from
the configuration, but in that case the end result is the same. Any of
the edge cases with provider or destroy provisioner configurations would
not apply, since there would not be any configuration references to
resolve.
Allow the evaluation of resource pending deleting only during a full
destroy. With this change we can ensure deposed instances are not
evaluated under normal circumstances, but can be references when needed.
This also allows us to remove the fixup transformer that added
connections so temporary values would evaluate in the correct order when
referencing destroy nodes.

In the majority of cases, we do not want to evaluate resources that are
pending deletion since configuration references only can refer to
resources that is intended to be managed by the configuration. An
exception to that rule is when Terraform is performing a full `destroy`
operation, and providers need to evaluate existing resources for their
configuration.
The test for this behavior did not work, because the old mock diff
function does not work correctly. Write a PlanResourceChange function to
return a correct plan.
In order to properly evaluate a destroy provisioner, we cannot rely on
the usual evaluation context, because the resource has already been
removed from the state.

EvalSelfBlock evaluates an hcl.Body in the limited scope of a single
object as "self", with the added values of "count.index" and "each.key".
@jbardin jbardin requested a review from a team October 2, 2020 16:07
@codecov
Copy link

codecov bot commented Oct 2, 2020

Codecov Report

Merging #26470 into master will decrease coverage by 0.06%.
The diff coverage is 54.54%.

Impacted Files Coverage Δ
lang/eval.go 59.78% <0.00%> (-5.53%) ⬇️
plans/changes_sync.go 0.00% <0.00%> (ø)
terraform/graph_builder_apply.go 100.00% <ø> (ø)
terraform/transform_reference.go 87.20% <ø> (-2.66%) ⬇️
terraform/node_resource_apply_instance.go 75.79% <71.42%> (-0.10%) ⬇️
terraform/eval_apply.go 73.08% <100.00%> (+1.20%) ⬆️
terraform/evaluate.go 49.66% <100.00%> (-0.68%) ⬇️
terraform/node_resource_plan.go 95.32% <0.00%> (-1.87%) ⬇️

@jbardin jbardin changed the title Only allow special-case evaluation of instances pending deletion. Allow special-case evaluation of instances pending deletion. Oct 2, 2020
Evaluate destroy provisioner configurations using only the last resource
state value, and the static instance key data.
@jbardin jbardin force-pushed the jbardin/inverse-destroy-references branch from d35e6df to 95197f0 Compare October 2, 2020 16:39
Copy link
Contributor

@mildwonkey mildwonkey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! I left one nitpicky comment about the name FullDestroy, but you are welcome to merge this as-is.

// refer to the last known value of the resource.
self := n.Change.Before

var evalScope func(EvalContext, hcl.Body, cty.Value, *configschema.Block) (cty.Value, tfdiags.Diagnostics)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 This is an interesting pattern; it took me a minute to get why but I do believe you'll be seeing it again when I get back to refactoring Eval() stuff. I like it.

The change was passed into the provisioner node because the normal
NodeApplyableResourceInstance overwrites the prior state with the new
state. This however doesn't matter here, because the resource destroy
node does not do this. Also, even if the updated state were to be used
for some reason with a create provisioner, it would be the correct state
to use at that point.
Copy link
Contributor

@mildwonkey mildwonkey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoops thought I'd already approved 😝 LGTM!

@jbardin jbardin merged commit c48af3f into master Oct 5, 2020
@jbardin jbardin deleted the jbardin/inverse-destroy-references branch October 5, 2020 20:20
@ghost
Copy link

ghost commented Nov 5, 2020

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.

@ghost ghost locked as resolved and limited conversation to collaborators Nov 5, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
2 participants