diff --git a/terraform/context.go b/terraform/context.go index d061b47a6..66e954245 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -331,6 +331,12 @@ func (c *Context) Plan() (*Plan, error) { } p.Diff = c.diff + // Now that we have a diff, we can build the exact graph that Apply will use + // and catch any possible cycles during the Plan phase. + if _, err := c.Graph(&ContextGraphOpts{Validate: true}); err != nil { + return nil, err + } + return p, nil } @@ -406,12 +412,11 @@ func (c *Context) Validate() ([]string, []error) { } } - // Build a Verbose version of the graph so we can catch any potential cycles - // in the validate stage - graph, err := c.Graph(&ContextGraphOpts{ - Validate: true, - Verbose: false, - }) + // Build the graph so we can walk it and run Validate on nodes. + // We also validate the graph generated here, but this graph doesn't + // necessarily match the graph that Plan will generate, so we'll validate the + // graph again later after Planning. + graph, err := c.Graph(&ContextGraphOpts{Validate: true}) if err != nil { return nil, []error{err} } diff --git a/terraform/graph_config_node_resource.go b/terraform/graph_config_node_resource.go index 2ad91d18d..7c94f098e 100644 --- a/terraform/graph_config_node_resource.go +++ b/terraform/graph_config_node_resource.go @@ -426,10 +426,13 @@ func (n *graphNodeResourceDestroy) destroyIncludePrimary( // to include this resource. prefix := n.Original.Resource.Id() - // If we're present in the diff proper, then keep it. + // If we're present in the diff proper, then keep it. We're looking + // only for resources in the diff that match our resource or a count-index + // of our resource that are marked for destroy. if d != nil { - for k, _ := range d.Resources { - if strings.HasPrefix(k, prefix) { + for k, d := range d.Resources { + match := k == prefix || strings.HasPrefix(k, prefix+".") + if match && d.Destroy { return true } } diff --git a/terraform/transform_destroy_test.go b/terraform/transform_destroy_test.go index 56acec049..1a50ce053 100644 --- a/terraform/transform_destroy_test.go +++ b/terraform/transform_destroy_test.go @@ -166,7 +166,7 @@ func TestPruneDestroyTransformer_diff(t *testing.T) { actual := strings.TrimSpace(g.String()) expected := strings.TrimSpace(testTransformPruneDestroyBasicDiffStr) if actual != expected { - t.Fatalf("bad:\n\n%s", actual) + t.Fatalf("expected:\n\n%s\n\nbad:\n\n%s", expected, actual) } } @@ -421,9 +421,7 @@ aws_instance.foo const testTransformPruneDestroyBasicDiffStr = ` aws_instance.bar - aws_instance.bar (destroy) aws_instance.foo -aws_instance.bar (destroy) aws_instance.foo `