diff --git a/terraform/graph_builder_apply_test.go b/terraform/graph_builder_apply_test.go index af1aa9779..98bab2377 100644 --- a/terraform/graph_builder_apply_test.go +++ b/terraform/graph_builder_apply_test.go @@ -600,6 +600,48 @@ test_object.b } } +// The orphan clean up node should not be connected to a provider +func TestApplyGraphBuilder_orphanedWithProvider(t *testing.T) { + changes := &plans.Changes{ + Resources: []*plans.ResourceInstanceChangeSrc{ + { + Addr: mustResourceInstanceAddr("test_object.A"), + ChangeSrc: plans.ChangeSrc{ + Action: plans.Delete, + }, + }, + }, + } + + state := states.NewState() + root := state.EnsureModule(addrs.RootModuleInstance) + root.SetResourceInstanceCurrent( + mustResourceInstanceAddr("test_object.A").Resource, + &states.ResourceInstanceObjectSrc{ + Status: states.ObjectReady, + AttrsJSON: []byte(`{"id":"A"}`), + }, + mustProviderConfig("provider.test.foo"), + ) + + b := &ApplyGraphBuilder{ + Config: testModule(t, "graph-builder-orphan-alias"), + Changes: changes, + Components: simpleMockComponentFactory(), + Schemas: simpleTestSchemas(), + State: state, + } + + g, err := b.Build(addrs.RootModuleInstance) + if err != nil { + t.Fatal(err) + } + + // The cleanup node has no state or config of its own, so would create a + // default provider which we don't want. + testGraphNotContains(t, g, "provider.test") +} + const testApplyGraphBuilderStr = ` meta.count-boundary (EachMode fixup) module.child.test_object.other diff --git a/terraform/node_resource_destroy.go b/terraform/node_resource_destroy.go index ca2267e47..c5042436d 100644 --- a/terraform/node_resource_destroy.go +++ b/terraform/node_resource_destroy.go @@ -277,36 +277,15 @@ func (n *NodeDestroyResourceInstance) EvalTree() EvalNode { // leaving skeleton resource objects in state after their instances have // all been destroyed. type NodeDestroyResource struct { - *NodeAbstractResource + NodeAbstractResource *NodeAbstractResource } var ( - _ GraphNodeResource = (*NodeDestroyResource)(nil) - _ GraphNodeReferenceable = (*NodeDestroyResource)(nil) - _ GraphNodeReferencer = (*NodeDestroyResource)(nil) - _ GraphNodeEvalable = (*NodeDestroyResource)(nil) + _ GraphNodeEvalable = (*NodeDestroyResource)(nil) ) func (n *NodeDestroyResource) Name() string { - return n.ResourceAddr().String() + " (clean up state)" -} - -// GraphNodeReferenceable, overriding NodeAbstractResource -func (n *NodeDestroyResource) ReferenceableAddrs() []addrs.Referenceable { - // NodeDestroyResource doesn't participate in references: the graph - // builder that created it should ensure directly that it already depends - // on every other node related to its resource, without relying on - // references. - return nil -} - -// GraphNodeReferencer, overriding NodeAbstractResource -func (n *NodeDestroyResource) References() []*addrs.Reference { - // NodeDestroyResource doesn't participate in references: the graph - // builder that created it should ensure directly that it already depends - // on every other node related to its resource, without relying on - // references. - return nil + return n.NodeAbstractResource.ResourceAddr().String() + " (clean up state)" } // GraphNodeEvalable @@ -316,6 +295,6 @@ func (n *NodeDestroyResource) EvalTree() EvalNode { // leftover husk of a resource in state after all of the child instances // and their objects were destroyed. return &EvalForgetResourceState{ - Addr: n.ResourceAddr().Resource, + Addr: n.NodeAbstractResource.ResourceAddr().Resource, } } diff --git a/terraform/testdata/graph-builder-orphan-alias/main.tf b/terraform/testdata/graph-builder-orphan-alias/main.tf new file mode 100644 index 000000000..039881847 --- /dev/null +++ b/terraform/testdata/graph-builder-orphan-alias/main.tf @@ -0,0 +1,3 @@ +provider "test" { + alias = "foo" +}