From 4a51e4fe9144a302fe3c16591b3741f72b647ce1 Mon Sep 17 00:00:00 2001 From: Paul Hinze Date: Wed, 20 Jan 2016 16:00:20 -0600 Subject: [PATCH] core: write planfile even on empty plans This makes the planfile workflow more consistent. If a plan yields a noop, the apply of that planfile will noop. Fixes #1783 --- command/plan.go | 18 ++++++++-------- command/plan_test.go | 49 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/command/plan.go b/command/plan.go index f0902e450..5582ddf4f 100644 --- a/command/plan.go +++ b/command/plan.go @@ -102,15 +102,6 @@ func (c *PlanCommand) Run(args []string) int { return 1 } - if plan.Diff.Empty() { - c.Ui.Output( - "No changes. Infrastructure is up-to-date. This means that Terraform\n" + - "could not detect any differences between your configuration and\n" + - "the real physical resources that exist. As a result, Terraform\n" + - "doesn't need to do anything.") - return 0 - } - if outPath != "" { log.Printf("[INFO] Writing plan output to: %s", outPath) f, err := os.Create(outPath) @@ -124,6 +115,15 @@ func (c *PlanCommand) Run(args []string) int { } } + if plan.Diff.Empty() { + c.Ui.Output( + "No changes. Infrastructure is up-to-date. This means that Terraform\n" + + "could not detect any differences between your configuration and\n" + + "the real physical resources that exist. As a result, Terraform\n" + + "doesn't need to do anything.") + return 0 + } + if outPath == "" { c.Ui.Output(strings.TrimSpace(planHeaderNoOutput) + "\n") } else { diff --git a/command/plan_test.go b/command/plan_test.go index d0d14bc56..9b89018bf 100644 --- a/command/plan_test.go +++ b/command/plan_test.go @@ -177,6 +177,55 @@ func TestPlan_outPath(t *testing.T) { } } +func TestPlan_outPathNoChange(t *testing.T) { + originalState := &terraform.State{ + Modules: []*terraform.ModuleState{ + &terraform.ModuleState{ + Path: []string{"root"}, + Resources: map[string]*terraform.ResourceState{ + "test_instance.foo": &terraform.ResourceState{ + Type: "test_instance", + Primary: &terraform.InstanceState{ + ID: "bar", + }, + }, + }, + }, + }, + } + statePath := testStateFile(t, originalState) + + tf, err := ioutil.TempFile("", "tf") + if err != nil { + t.Fatalf("err: %s", err) + } + outPath := tf.Name() + os.Remove(tf.Name()) + + p := testProvider() + ui := new(cli.MockUi) + c := &PlanCommand{ + Meta: Meta{ + ContextOpts: testCtxConfig(p), + Ui: ui, + }, + } + + args := []string{ + "-out", outPath, + "-state", statePath, + testFixturePath("plan"), + } + if code := c.Run(args); code != 0 { + t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) + } + + plan := testReadPlan(t, outPath) + if !plan.Diff.Empty() { + t.Fatalf("Expected empty plan to be written to plan file, got: %s", plan) + } +} + func TestPlan_refresh(t *testing.T) { p := testProvider() ui := new(cli.MockUi)