mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
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:
parent
73c3994455
commit
3779dbc2af
@ -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)
|
||||
}
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user