From 8671f407687650f3056e7670b949c084ae5a2b5b Mon Sep 17 00:00:00 2001 From: James Bardin Date: Sun, 21 Mar 2021 12:14:47 -0400 Subject: [PATCH 1/3] connect destroyers to all stored create deps We currently count on interconnecting destroy nodes to handle the create->destroy dependency edge for replacement, but when the create node is only an update we don't connect that edge directly. Lookup all creators that are dependencies of the destory node and ensure they are connected. --- terraform/transform_destroy_edge.go | 44 +++++++++++++++++++---------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/terraform/transform_destroy_edge.go b/terraform/transform_destroy_edge.go index c3f15871b..9a177cbe2 100644 --- a/terraform/transform_destroy_edge.go +++ b/terraform/transform_destroy_edge.go @@ -59,7 +59,7 @@ func (t *DestroyEdgeTransformer) Transform(g *Graph) error { // Record the creators, which will need to depend on the destroyers if they // are only being updated. - creators := make(map[string]GraphNodeCreator) + creators := make(map[string][]GraphNodeCreator) // destroyersByResource records each destroyer by the ConfigResource // address. We use this because dependencies are only referenced as @@ -83,8 +83,8 @@ func (t *DestroyEdgeTransformer) Transform(g *Graph) error { resAddr := addr.ContainingResource().Config().String() destroyersByResource[resAddr] = append(destroyersByResource[resAddr], n) case GraphNodeCreator: - addr := n.CreateAddr() - creators[addr.String()] = n + addr := n.CreateAddr().ContainingResource().Config().String() + creators[addr] = append(creators[addr], n) } } @@ -111,24 +111,38 @@ func (t *DestroyEdgeTransformer) Transform(g *Graph) error { log.Printf("[TRACE] DestroyEdgeTransformer: skipping %s => %s inter-module-instance dependency\n", dag.VertexName(desDep), dag.VertexName(des)) } } + + // We can have some create or update nodes which were + // dependents of the destroy node. If they have no destroyer + // themselves, make the connection directly from the creator. + for _, createDep := range creators[resAddr.String()] { + if !graphNodesAreResourceInstancesInDifferentInstancesOfSameModule(createDep, des) { + log.Printf("[DEBUG] DestroyEdgeTransformer: %s has stored dependency of %s\n", dag.VertexName(createDep), dag.VertexName(des)) + g.Connect(dag.BasicEdge(createDep, des)) + } else { + log.Printf("[TRACE] DestroyEdgeTransformer: skipping %s => %s inter-module-instance dependency\n", dag.VertexName(createDep), dag.VertexName(des)) + } + } } } } // connect creators to any destroyers on which they may depend - for _, c := range creators { - ri, ok := c.(GraphNodeResourceInstance) - if !ok { - continue - } + for _, cs := range creators { + for _, c := range cs { + ri, ok := c.(GraphNodeResourceInstance) + if !ok { + continue + } - for _, resAddr := range ri.StateDependencies() { - for _, desDep := range destroyersByResource[resAddr.String()] { - if !graphNodesAreResourceInstancesInDifferentInstancesOfSameModule(c, desDep) { - log.Printf("[TRACE] DestroyEdgeTransformer: %s has stored dependency of %s\n", dag.VertexName(c), dag.VertexName(desDep)) - g.Connect(dag.BasicEdge(c, desDep)) - } else { - log.Printf("[TRACE] DestroyEdgeTransformer: skipping %s => %s inter-module-instance dependency\n", dag.VertexName(c), dag.VertexName(desDep)) + for _, resAddr := range ri.StateDependencies() { + for _, desDep := range destroyersByResource[resAddr.String()] { + if !graphNodesAreResourceInstancesInDifferentInstancesOfSameModule(c, desDep) { + log.Printf("[TRACE] DestroyEdgeTransformer: %s has stored dependency of %s\n", dag.VertexName(c), dag.VertexName(desDep)) + g.Connect(dag.BasicEdge(c, desDep)) + } else { + log.Printf("[TRACE] DestroyEdgeTransformer: skipping %s => %s inter-module-instance dependency\n", dag.VertexName(c), dag.VertexName(desDep)) + } } } } From 0bc64e3cc462e0ced0b4760ce1eda23f7f0c361e Mon Sep 17 00:00:00 2001 From: James Bardin Date: Mon, 22 Mar 2021 14:18:36 -0400 Subject: [PATCH 2/3] tests for destroy-then-update dependency ordering --- terraform/context_apply2_test.go | 71 ++++++++++++++++++++++++ terraform/transform_destroy_edge_test.go | 64 ++++++++++++++++++++- 2 files changed, 133 insertions(+), 2 deletions(-) diff --git a/terraform/context_apply2_test.go b/terraform/context_apply2_test.go index a739db2ad..e0484197c 100644 --- a/terraform/context_apply2_test.go +++ b/terraform/context_apply2_test.go @@ -3,7 +3,9 @@ package terraform import ( "errors" "fmt" + "sync" "testing" + "time" "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/providers" @@ -177,3 +179,72 @@ output "data" { t.Fatal(diags.Err()) } } + +func TestContext2Apply_destroyThenUpdate(t *testing.T) { + m := testModuleInline(t, map[string]string{ + "main.tf": ` +resource "test_instance" "a" { + value = "udpated" +} +`, + }) + + p := testProvider("test") + p.PlanResourceChangeFn = testDiffFn + + var orderMu sync.Mutex + var order []string + p.ApplyResourceChangeFn = func(req providers.ApplyResourceChangeRequest) (resp providers.ApplyResourceChangeResponse) { + id := req.PriorState.GetAttr("id").AsString() + if id == "b" { + // slow down the b destroy, since a should wait for it + time.Sleep(100 * time.Millisecond) + } + + orderMu.Lock() + order = append(order, id) + orderMu.Unlock() + + resp.NewState = req.PlannedState + return resp + } + + addrA := mustResourceInstanceAddr(`test_instance.a`) + addrB := mustResourceInstanceAddr(`test_instance.b`) + + state := states.BuildState(func(s *states.SyncState) { + s.SetResourceInstanceCurrent(addrA, &states.ResourceInstanceObjectSrc{ + AttrsJSON: []byte(`{"id":"a","value":"old","type":"test"}`), + Status: states.ObjectReady, + }, mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`)) + + // test_instance.b depended on test_instance.a, and therefor should be + // destroyed before any changes to test_instance.a + s.SetResourceInstanceCurrent(addrB, &states.ResourceInstanceObjectSrc{ + AttrsJSON: []byte(`{"id":"b"}`), + Status: states.ObjectReady, + Dependencies: []addrs.ConfigResource{addrA.ContainingResource().Config()}, + }, mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`)) + }) + + ctx := testContext2(t, &ContextOpts{ + Config: m, + State: state, + Providers: map[addrs.Provider]providers.Factory{ + addrs.NewDefaultProvider("test"): testProviderFuncFixed(p), + }, + }) + + if _, diags := ctx.Plan(); diags.HasErrors() { + t.Fatal(diags.Err()) + } + + _, diags := ctx.Apply() + if diags.HasErrors() { + t.Fatal(diags.Err()) + } + + if order[0] != "b" { + t.Fatalf("expected apply order [b, a], got: %v\n", order) + } +} diff --git a/terraform/transform_destroy_edge_test.go b/terraform/transform_destroy_edge_test.go index 4d0c63ebb..92b2448fd 100644 --- a/terraform/transform_destroy_edge_test.go +++ b/terraform/transform_destroy_edge_test.go @@ -260,14 +260,74 @@ module.child[1].test_object.c (destroy) } } +func TestDestroyEdgeTransformer_destroyThenUpdate(t *testing.T) { + g := Graph{Path: addrs.RootModuleInstance} + g.Add(testUpdateNode("test_object.A")) + g.Add(testDestroyNode("test_object.B")) + + state := states.NewState() + root := state.EnsureModule(addrs.RootModuleInstance) + root.SetResourceInstanceCurrent( + mustResourceInstanceAddr("test_object.A").Resource, + &states.ResourceInstanceObjectSrc{ + Status: states.ObjectReady, + AttrsJSON: []byte(`{"id":"A","test_string":"old"}`), + }, + mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`), + ) + root.SetResourceInstanceCurrent( + mustResourceInstanceAddr("test_object.B").Resource, + &states.ResourceInstanceObjectSrc{ + Status: states.ObjectReady, + AttrsJSON: []byte(`{"id":"B","test_string":"x"}`), + Dependencies: []addrs.ConfigResource{mustConfigResourceAddr("test_object.A")}, + }, + mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`), + ) + + if err := (&AttachStateTransformer{State: state}).Transform(&g); err != nil { + t.Fatal(err) + } + + m := testModuleInline(t, map[string]string{ + "main.tf": ` +resource "test_instance" "a" { + test_string = "udpated" +} +`, + }) + tf := &DestroyEdgeTransformer{ + Config: m, + Schemas: simpleTestSchemas(), + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + expected := strings.TrimSpace(` +test_object.A + test_object.B (destroy) +test_object.B (destroy) +`) + actual := strings.TrimSpace(g.String()) + + if actual != expected { + t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) + } +} + func testDestroyNode(addrString string) GraphNodeDestroyer { instAddr := mustResourceInstanceAddr(addrString) - inst := NewNodeAbstractResourceInstance(instAddr) - return &NodeDestroyResourceInstance{NodeAbstractResourceInstance: inst} } +func testUpdateNode(addrString string) GraphNodeCreator { + instAddr := mustResourceInstanceAddr(addrString) + inst := NewNodeAbstractResourceInstance(instAddr) + return &NodeApplyableResourceInstance{NodeAbstractResourceInstance: inst} +} + const testTransformDestroyEdgeBasicStr = ` test_object.A (destroy) test_object.B (destroy) From dcb12195a306c4cda64a2c941ea7d40cfe149603 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Mon, 22 Mar 2021 15:05:53 -0400 Subject: [PATCH 3/3] update destroying.md Update the full-replacement example graph to show the transitive dependency that is required for the destroy-then-update case. Add another example describing the case where we reduce the graph to only an update and replace and the dependency on the destroy node remains. --- docs/destroying.md | 23 +++++++++++++++++++++++ docs/images/destroy_then_update.png | Bin 0 -> 8741 bytes docs/images/replace_all.png | Bin 11773 -> 12463 bytes 3 files changed, 23 insertions(+) create mode 100644 docs/images/destroy_then_update.png diff --git a/docs/destroying.md b/docs/destroying.md index 4d821a2ee..27cb17106 100644 --- a/docs/destroying.md +++ b/docs/destroying.md @@ -114,6 +114,7 @@ digraph replacement { } a -> a_d; + a -> b_d [style=dotted]; b -> a_d [style=dotted]; b -> b_d; } @@ -158,6 +159,28 @@ While the dependency edge from `B update` to `A destroy` isn't necessary in these examples, it is shown here as an implementation detail which will be mentioned later on. +A final example based on the replacement graph; starting with the above +configuration where `B` depends on `A`. The graph is reduced to an update of +`A` while only destroying `B`. The interesting feature here is the remaining +dependency of `A update` on `B destroy`. We can derive this ordering of +operations from the full replacement example above, by replacing `A create` +with `A update` and removing the unused nodes. + +![Replace All](./images/destroy_then_update.png) + ## Create Before Destroy Currently, the only user-controllable method for changing the ordering of diff --git a/docs/images/destroy_then_update.png b/docs/images/destroy_then_update.png new file mode 100644 index 0000000000000000000000000000000000000000..f4f3d209c7536b7306829de55adf43367a24c789 GIT binary patch literal 8741 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 P0i~*V2U8;d=+*xLrDoGG literal 11773 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 S&M@?IBZ~LbWJ{$@0{$0x9?rl3