From 1fa3840a00968c167fe1817abd2e25817830ec1e Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 26 Sep 2014 09:20:01 -0700 Subject: [PATCH] terraform: handle module dependencies with a diff --- terraform/graph.go | 19 ++++- terraform/graph_test.go | 75 +++++++++++++++++++ .../graph-diff-module/child/main.tf | 5 ++ .../test-fixtures/graph-diff-module/main.tf | 7 ++ 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 terraform/test-fixtures/graph-diff-module/child/main.tf create mode 100644 terraform/test-fixtures/graph-diff-module/main.tf diff --git a/terraform/graph.go b/terraform/graph.go index ae8f1c0cb..99d6561f6 100644 --- a/terraform/graph.go +++ b/terraform/graph.go @@ -601,6 +601,23 @@ func graphAddDiff(g *depgraph.Graph, d *ModuleDiff) error { num-- i-- + case *GraphNodeModule: + // We invert any module dependencies so we're destroyed + // first, before any modules are applied. + newDep := &depgraph.Dependency{ + Name: n.Name, + Source: dep.Target, + Target: n, + } + dep.Target.Deps = append(dep.Target.Deps, newDep) + + // Drop the dependency. We may have created + // an inverse depedency if the dependent resource + // is also being deleted, but this dependence is + // no longer required. + deps[i], deps[num-1] = deps[num-1], nil + num-- + i-- case *GraphNodeResourceProvider: // Keep these around, but fix up the source to be ourselves // rather than the old node. @@ -608,7 +625,7 @@ func graphAddDiff(g *depgraph.Graph, d *ModuleDiff) error { newDep.Source = n deps[i] = &newDep default: - panic(fmt.Errorf("Unhandled depedency type: %#v", dep.Meta)) + panic(fmt.Errorf("Unhandled depedency type: %#v", dep.Target.Meta)) } } n.Deps = deps[:num] diff --git a/terraform/graph_test.go b/terraform/graph_test.go index 689e6d259..fd2e0894b 100644 --- a/terraform/graph_test.go +++ b/terraform/graph_test.go @@ -624,6 +624,68 @@ func TestGraphAddDiff_destroy_counts(t *testing.T) { } } +func TestGraphAddDiff_module(t *testing.T) { + m := testModule(t, "graph-diff-module") + diff := &Diff{ + Modules: []*ModuleDiff{ + &ModuleDiff{ + Path: rootModulePath, + Resources: map[string]*InstanceDiff{ + "aws_instance.foo": &InstanceDiff{ + Destroy: true, + }, + }, + }, + }, + } + + g, err := Graph(&GraphOpts{Module: m, Diff: diff}) + if err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + expected := strings.TrimSpace(testTerraformGraphDiffModuleStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) + } +} + +func TestGraphAddDiff_moduleDestroy(t *testing.T) { + m := testModule(t, "graph-diff-module") + diff := &Diff{ + Modules: []*ModuleDiff{ + &ModuleDiff{ + Path: rootModulePath, + Resources: map[string]*InstanceDiff{ + "aws_instance.foo": &InstanceDiff{ + Destroy: true, + }, + }, + }, + &ModuleDiff{ + Path: []string{"root", "child"}, + Resources: map[string]*InstanceDiff{ + "aws_instance.foo": &InstanceDiff{ + Destroy: true, + }, + }, + }, + }, + } + + g, err := Graph(&GraphOpts{Module: m, Diff: diff}) + if err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + expected := strings.TrimSpace(testTerraformGraphDiffModuleStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) + } +} + func TestGraphEncodeDependencies(t *testing.T) { m := testModule(t, "graph-basic") state := &State{ @@ -873,6 +935,19 @@ root root -> aws_load_balancer.weblb ` +const testTerraformGraphDiffModuleStr = ` +root: root +aws_instance.foo + aws_instance.foo -> aws_instance.foo (destroy) + aws_instance.foo -> module.child +aws_instance.foo (destroy) +module.child + module.child -> aws_instance.foo (destroy) +root + root -> aws_instance.foo + root -> module.child +` + const testTerraformGraphModulesStr = ` root: root aws_instance.web diff --git a/terraform/test-fixtures/graph-diff-module/child/main.tf b/terraform/test-fixtures/graph-diff-module/child/main.tf new file mode 100644 index 000000000..84d1de905 --- /dev/null +++ b/terraform/test-fixtures/graph-diff-module/child/main.tf @@ -0,0 +1,5 @@ +resource "aws_instance" "foo" {} + +output "bar" { + value = "baz" +} diff --git a/terraform/test-fixtures/graph-diff-module/main.tf b/terraform/test-fixtures/graph-diff-module/main.tf new file mode 100644 index 000000000..2b823f117 --- /dev/null +++ b/terraform/test-fixtures/graph-diff-module/main.tf @@ -0,0 +1,7 @@ +module "child" { + source = "./child" +} + +resource "aws_instance" "foo" { + value = "${module.child.bar}" +}