From 77b1c7daa039a2a64c544bcb3c257e1bf5b7b0a2 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 25 Sep 2014 20:44:34 -0700 Subject: [PATCH] terraform: destroy plans work with modules --- terraform/context.go | 37 +++++++++----- terraform/context_test.go | 50 +++++++++++++++++++ terraform/terraform_test.go | 18 +++++++ .../plan-module-destroy/child/main.tf | 3 ++ .../test-fixtures/plan-module-destroy/main.tf | 7 +++ 5 files changed, 103 insertions(+), 12 deletions(-) create mode 100644 terraform/test-fixtures/plan-module-destroy/child/main.tf create mode 100644 terraform/test-fixtures/plan-module-destroy/main.tf diff --git a/terraform/context.go b/terraform/context.go index da61f3552..e0bb147ca 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -703,20 +703,33 @@ func (c *walkContext) planDestroyWalkFn() depgraph.WalkFunc { result.init() return func(n *depgraph.Noun) error { - rn, ok := n.Meta.(*GraphNodeResource) - if !ok { - return nil - } + switch m := n.Meta.(type) { + case *GraphNodeModule: + // Build another walkContext for this module and walk it. + wc := c.Context.walkContext(c.Operation, m.Path) - r := rn.Resource - if r.State != nil && r.State.ID != "" { - log.Printf("[DEBUG] %s: Making for destroy", r.Id) + // Set the graph to specifically walk this subgraph + wc.graph = m.Graph - l.Lock() - defer l.Unlock() - result.Diff.RootModule().Resources[r.Id] = &InstanceDiff{Destroy: true} - } else { - log.Printf("[DEBUG] %s: Not marking for destroy, no ID", r.Id) + // Preserve the meta + wc.Meta = c.Meta + + return wc.Walk() + case *GraphNodeResource: + r := m.Resource + if r.State != nil && r.State.ID != "" { + log.Printf("[DEBUG] %s: Making for destroy", r.Id) + + l.Lock() + defer l.Unlock() + md := result.Diff.ModuleByPath(c.Path) + if md == nil { + md = result.Diff.AddModule(c.Path) + } + md.Resources[r.Id] = &InstanceDiff{Destroy: true} + } else { + log.Printf("[DEBUG] %s: Not marking for destroy, no ID", r.Id) + } } return nil diff --git a/terraform/context_test.go b/terraform/context_test.go index e3b22dea5..72d9f0a4d 100644 --- a/terraform/context_test.go +++ b/terraform/context_test.go @@ -2117,6 +2117,56 @@ func TestContextPlan_destroy(t *testing.T) { } } +func TestContextPlan_moduleDestroy(t *testing.T) { + m := testModule(t, "plan-module-destroy") + p := testProvider("aws") + p.DiffFn = testDiffFn + s := &State{ + Modules: []*ModuleState{ + &ModuleState{ + Path: rootModulePath, + Resources: map[string]*ResourceState{ + "aws_instance.foo": &ResourceState{ + Type: "aws_instance", + Primary: &InstanceState{ + ID: "bar", + }, + }, + }, + }, + &ModuleState{ + Path: []string{"root", "child"}, + Resources: map[string]*ResourceState{ + "aws_instance.foo": &ResourceState{ + Type: "aws_instance", + Primary: &InstanceState{ + ID: "bar", + }, + }, + }, + }, + }, + } + ctx := testContext(t, &ContextOpts{ + Module: m, + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, + State: s, + }) + + plan, err := ctx.Plan(&PlanOpts{Destroy: true}) + if err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(plan.String()) + expected := strings.TrimSpace(testTerraformPlanModuleDestroyStr) + if actual != expected { + t.Fatalf("bad:\n%s", actual) + } +} + func TestContextPlan_diffVar(t *testing.T) { m := testModule(t, "plan-diffvar") p := testProvider("aws") diff --git a/terraform/terraform_test.go b/terraform/terraform_test.go index 785b68675..660519ded 100644 --- a/terraform/terraform_test.go +++ b/terraform/terraform_test.go @@ -528,6 +528,24 @@ STATE: ` +const testTerraformPlanModuleDestroyStr = ` +DIFF: + +DESTROY: aws_instance.foo + +module.child: + DESTROY: aws_instance.foo + +STATE: + +aws_instance.foo: + ID = bar + +module.child: + aws_instance.foo: + ID = bar +` + const testTerraformPlanModuleInputStr = ` DIFF: diff --git a/terraform/test-fixtures/plan-module-destroy/child/main.tf b/terraform/test-fixtures/plan-module-destroy/child/main.tf new file mode 100644 index 000000000..98f5ee87e --- /dev/null +++ b/terraform/test-fixtures/plan-module-destroy/child/main.tf @@ -0,0 +1,3 @@ +resource "aws_instance" "foo" { + num = "2" +} diff --git a/terraform/test-fixtures/plan-module-destroy/main.tf b/terraform/test-fixtures/plan-module-destroy/main.tf new file mode 100644 index 000000000..428f89834 --- /dev/null +++ b/terraform/test-fixtures/plan-module-destroy/main.tf @@ -0,0 +1,7 @@ +module "child" { + source = "./child" +} + +resource "aws_instance" "foo" { + num = "2" +}