From f47956d62f01e2c630cc1a0b76d578f3737f1262 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 22 Jul 2014 18:20:03 -0700 Subject: [PATCH] terraform: dependsOn builds into the graph --- terraform/graph.go | 45 +++++++++++++++++++ terraform/graph_test.go | 25 +++++++++++ .../test-fixtures/graph-depends-on/main.tf | 5 +++ 3 files changed, 75 insertions(+) create mode 100644 terraform/test-fixtures/graph-depends-on/main.tf diff --git a/terraform/graph.go b/terraform/graph.go index 2d8bb92d5..db3889a2e 100644 --- a/terraform/graph.go +++ b/terraform/graph.go @@ -106,6 +106,9 @@ func Graph(opts *GraphOpts) (*depgraph.Graph, error) { // and no dependencies. graphAddConfigResources(g, opts.Config, opts.State) + // Add explicit dependsOn dependencies to the graph + graphAddExplicitDeps(g) + // Next, add the state orphans if we have any if opts.State != nil { graphAddOrphans(g, opts.Config, opts.State) @@ -377,6 +380,48 @@ func graphAddDiff(g *depgraph.Graph, d *Diff) error { return nil } +// graphAddExplicitDeps adds the dependencies to the graph for the explicit +// dependsOn configurations. +func graphAddExplicitDeps(g *depgraph.Graph) { + depends := false + + rs := make(map[string]*depgraph.Noun) + for _, n := range g.Nouns { + rn, ok := n.Meta.(*GraphNodeResource) + if !ok { + continue + } + + rs[rn.Config.Id()] = n + if len(rn.Config.DependsOn) > 0 { + depends = true + } + } + + // If we didn't have any dependsOn, just return + if !depends { + return + } + + for _, n1 := range rs { + rn1 := n1.Meta.(*GraphNodeResource) + for _, d := range rn1.Config.DependsOn { + for _, n2 := range rs { + rn2 := n2.Meta.(*GraphNodeResource) + if rn2.Config.Id() != d { + continue + } + + n1.Deps = append(n1.Deps, &depgraph.Dependency{ + Name: d, + Source: n1, + Target: n2, + }) + } + } + } +} + // graphAddMissingResourceProviders adds GraphNodeResourceProvider nodes for // the resources that do not have an explicit resource provider specified // because no provider configuration was given. diff --git a/terraform/graph_test.go b/terraform/graph_test.go index 4d1795878..dcbeb7ce1 100644 --- a/terraform/graph_test.go +++ b/terraform/graph_test.go @@ -51,6 +51,21 @@ func TestGraph_cycle(t *testing.T) { } } +func TestGraph_dependsOn(t *testing.T) { + config := testConfig(t, "graph-depends-on") + + g, err := Graph(&GraphOpts{Config: config}) + if err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + expected := strings.TrimSpace(testTerraformGraphDependsStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) + } +} + func TestGraph_state(t *testing.T) { config := testConfig(t, "graph-basic") state := &State{ @@ -347,6 +362,16 @@ root root -> aws_load_balancer.weblb ` +const testTerraformGraphDependsStr = ` +root: root +aws_instance.db + aws_instance.db -> aws_instance.web +aws_instance.web +root + root -> aws_instance.db + root -> aws_instance.web +` + const testTerraformGraphDiffStr = ` root: root aws_instance.foo diff --git a/terraform/test-fixtures/graph-depends-on/main.tf b/terraform/test-fixtures/graph-depends-on/main.tf new file mode 100644 index 000000000..2a2d904dc --- /dev/null +++ b/terraform/test-fixtures/graph-depends-on/main.tf @@ -0,0 +1,5 @@ +resource "aws_instance" "web" {} + +resource "aws_instance" "db" { + depends_on = ["aws_instance.web"] +}