noop orphan change has nothing to apply

An orphaned resource which plans as a NoOp change will have no config.
This is not an error, but there is nothing to do since there are also
no checks to validate. We still leave the change in the plan to keep the
plan as complete as possible, noting all possible changes.

Preventing the node from being added to the graph is awkward, because
the config is attached separately from the diff transformer. This should
not pose any problems however, because there is no longer any state or
config linking the instance to any dependencies in the graph.
This commit is contained in:
James Bardin 2022-10-11 14:30:29 -04:00
parent 73c3994455
commit 3779dbc2af
2 changed files with 53 additions and 5 deletions

View File

@ -1442,3 +1442,46 @@ resource "test_object" "x" {
t.Fatalf("apply: %s", diags.Err())
}
}
func TestContext2Apply_missingOrphanedResource(t *testing.T) {
m := testModuleInline(t, map[string]string{
"main.tf": `
# changed resource address to create a new object
resource "test_object" "y" {
test_string = "y"
}
`,
})
p := simpleMockProvider()
// report the prior value is missing
p.ReadResourceFn = func(req providers.ReadResourceRequest) (resp providers.ReadResourceResponse) {
resp.NewState = cty.NullVal(req.PriorState.Type())
return resp
}
state := states.NewState()
root := state.EnsureModule(addrs.RootModuleInstance)
root.SetResourceInstanceCurrent(
mustResourceInstanceAddr("test_object.x").Resource,
&states.ResourceInstanceObjectSrc{
Status: states.ObjectReady,
AttrsJSON: []byte(`{"test_string":"x"}`),
},
mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
)
ctx := testContext2(t, &ContextOpts{
Providers: map[addrs.Provider]providers.Factory{
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
},
})
opts := SimplePlanOpts(plans.NormalMode, nil)
plan, diags := ctx.Plan(m, state, opts)
assertNoErrors(t, diags)
_, diags = ctx.Apply(plan, m)
assertNoErrors(t, diags)
}

View File

@ -113,11 +113,16 @@ func (n *NodeApplyableResourceInstance) Execute(ctx EvalContext, op walkOperatio
addr := n.ResourceInstanceAddr()
if n.Config == nil {
// This should not be possible, but we've got here in at least one
// case as discussed in the following issue:
// https://github.com/hashicorp/terraform/issues/21258
// To avoid an outright crash here, we'll instead return an explicit
// error.
// If there is no config, and there is no change, then we have nothing
// to do and the change was left in the plan for informational
// purposes only.
changes := ctx.Changes()
csrc := changes.GetResourceInstanceChange(n.ResourceInstanceAddr(), states.CurrentGen)
if csrc == nil || csrc.Action == plans.NoOp {
log.Printf("[DEBUG] NodeApplyableResourceInstance: No config or planned change recorded for %s", n.Addr)
return nil
}
diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error,
"Resource node has no configuration attached",