diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index 55d653692..aef5848d6 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -3123,6 +3123,76 @@ func TestContext2Apply_provisionerMultiSelfRefCount(t *testing.T) { } } +func TestContext2Apply_provisionerExplicitSelfRef(t *testing.T) { + m := testModule(t, "apply-provisioner-explicit-self-ref") + p := testProvider("aws") + pr := testProvisioner() + p.ApplyFn = testApplyFn + p.DiffFn = testDiffFn + pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error { + val, ok := c.Config["command"] + if !ok || val != "bar" { + t.Fatalf("bad value for command: %v %#v", val, c) + } + + return nil + } + + var state *State + { + ctx := testContext2(t, &ContextOpts{ + Module: m, + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, + Provisioners: map[string]ResourceProvisionerFactory{ + "shell": testProvisionerFuncFixed(pr), + }, + }) + + _, err := ctx.Plan() + if err != nil { + t.Fatalf("err: %s", err) + } + + state, err = ctx.Apply() + if err != nil { + t.Fatalf("err: %s", err) + } + + // Verify apply was invoked + if !pr.ApplyCalled { + t.Fatalf("provisioner not invoked") + } + } + + { + ctx := testContext2(t, &ContextOpts{ + Module: m, + Destroy: true, + State: state, + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, + Provisioners: map[string]ResourceProvisionerFactory{ + "shell": testProvisionerFuncFixed(pr), + }, + }) + + _, err := ctx.Plan() + if err != nil { + t.Fatalf("err: %s", err) + } + + state, err = ctx.Apply() + if err != nil { + t.Fatalf("err: %s", err) + } + + checkStateString(t, state, ``) + } +} + // Provisioner should NOT run on a diff, only create func TestContext2Apply_Provisioner_Diff(t *testing.T) { m := testModule(t, "apply-provisioner-diff") diff --git a/terraform/test-fixtures/apply-provisioner-explicit-self-ref/main.tf b/terraform/test-fixtures/apply-provisioner-explicit-self-ref/main.tf new file mode 100644 index 000000000..7ceca47db --- /dev/null +++ b/terraform/test-fixtures/apply-provisioner-explicit-self-ref/main.tf @@ -0,0 +1,7 @@ +resource "aws_instance" "foo" { + foo = "bar" + + provisioner "shell" { + command = "${aws_instance.foo.foo}" + } +} diff --git a/terraform/test-fixtures/transform-destroy-edge-self-ref/main.tf b/terraform/test-fixtures/transform-destroy-edge-self-ref/main.tf new file mode 100644 index 000000000..d91e024c4 --- /dev/null +++ b/terraform/test-fixtures/transform-destroy-edge-self-ref/main.tf @@ -0,0 +1,5 @@ +resource "test" "A" { + provisioner "foo" { + command = "${test.A.id}" + } +} diff --git a/terraform/transform_destroy_edge.go b/terraform/transform_destroy_edge.go index a3a8f8d9f..972d9b6a2 100644 --- a/terraform/transform_destroy_edge.go +++ b/terraform/transform_destroy_edge.go @@ -182,7 +182,9 @@ func (t *DestroyEdgeTransformer) Transform(g *Graph) error { // names "a_d" and "b_d" to reference our example. for _, a_d := range dns { for _, b_d := range depDestroyers { - g.Connect(dag.BasicEdge(b_d, a_d)) + if b_d != a_d { + g.Connect(dag.BasicEdge(b_d, a_d)) + } } } } diff --git a/terraform/transform_destroy_edge_test.go b/terraform/transform_destroy_edge_test.go index e2c1a8a37..9489b5a5c 100644 --- a/terraform/transform_destroy_edge_test.go +++ b/terraform/transform_destroy_edge_test.go @@ -61,6 +61,23 @@ func TestDestroyEdgeTransformer_multi(t *testing.T) { } } +func TestDestroyEdgeTransformer_selfRef(t *testing.T) { + g := Graph{Path: RootModulePath} + g.Add(&graphNodeDestroyerTest{AddrString: "test.A"}) + tf := &DestroyEdgeTransformer{ + Module: testModule(t, "transform-destroy-edge-self-ref"), + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + expected := strings.TrimSpace(testTransformDestroyEdgeSelfRefStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) + } +} + type graphNodeCreatorTest struct { AddrString string } @@ -112,3 +129,7 @@ test.B (destroy) test.C (destroy) test.C (destroy) ` + +const testTransformDestroyEdgeSelfRefStr = ` +test.A (destroy) +`