diff --git a/terraform/diff.go b/terraform/diff.go index d6dc55061..b6651c0a8 100644 --- a/terraform/diff.go +++ b/terraform/diff.go @@ -396,6 +396,11 @@ type ResourceAttrDiff struct { Type DiffAttrType } +// Modified returns the inequality of Old and New for this attr +func (d *ResourceAttrDiff) Modified() bool { + return d.Old != d.New +} + // Empty returns true if the diff for this attr is neutral func (d *ResourceAttrDiff) Empty() bool { return d.Old == d.New && !d.NewComputed && !d.NewRemoved diff --git a/terraform/eval_diff.go b/terraform/eval_diff.go index bbc2b3667..c1def9166 100644 --- a/terraform/eval_diff.go +++ b/terraform/eval_diff.go @@ -258,9 +258,11 @@ func (n *EvalDiff) processIgnoreChanges(diff *InstanceDiff) error { for _, v := range containers { if v.keepDiff() { // At least one key has changes, so list all the sibling keys - // to keep in the diff. + // to keep in the diff if any values have changed for k := range v { - keep[k] = true + if v[k].Modified() { + keep[k] = true + } } } } diff --git a/terraform/eval_diff_test.go b/terraform/eval_diff_test.go index 1291e6993..0da3b0ee6 100644 --- a/terraform/eval_diff_test.go +++ b/terraform/eval_diff_test.go @@ -3,6 +3,8 @@ package terraform import ( "reflect" "testing" + + "github.com/hashicorp/terraform/config" ) func TestEvalFilterDiff(t *testing.T) { @@ -76,3 +78,69 @@ func TestEvalFilterDiff(t *testing.T) { } } } + +func TestProcessIgnoreChangesOnResourceIgnoredWithRequiresNew(t *testing.T) { + var evalDiff *EvalDiff + var instanceDiff *InstanceDiff + + var testDiffs = func(ignoreChanges []string, newAttribute string) (*EvalDiff, *InstanceDiff) { + return &EvalDiff{ + Resource: &config.Resource{ + Lifecycle: config.ResourceLifecycle{ + IgnoreChanges: ignoreChanges, + }, + }, + }, + &InstanceDiff{ + Destroy: true, + Attributes: map[string]*ResourceAttrDiff{ + "resource.changed": { + RequiresNew: true, + Type: DiffAttrInput, + Old: "old", + New: "new", + }, + "resource.unchanged": { + Old: "unchanged", + New: newAttribute, + }, + }, + } + } + + evalDiff, instanceDiff = testDiffs([]string{"resource.changed"}, "unchanged") + err := evalDiff.processIgnoreChanges(instanceDiff) + if err != nil { + t.Fatalf("err: %s", err) + } + if len(instanceDiff.Attributes) > 0 { + t.Fatalf("Expected all resources to be ignored, found %d", len(instanceDiff.Attributes)) + } + + evalDiff, instanceDiff = testDiffs([]string{}, "unchanged") + err = evalDiff.processIgnoreChanges(instanceDiff) + if err != nil { + t.Fatalf("err: %s", err) + } + if len(instanceDiff.Attributes) != 2 { + t.Fatalf("Expected 2 resources to be found, found %d", len(instanceDiff.Attributes)) + } + + evalDiff, instanceDiff = testDiffs([]string{"resource.changed"}, "changed") + err = evalDiff.processIgnoreChanges(instanceDiff) + if err != nil { + t.Fatalf("err: %s", err) + } + if len(instanceDiff.Attributes) != 1 { + t.Fatalf("Expected 1 resource to be found, found %d", len(instanceDiff.Attributes)) + } + + evalDiff, instanceDiff = testDiffs([]string{}, "changed") + err = evalDiff.processIgnoreChanges(instanceDiff) + if err != nil { + t.Fatalf("err: %s", err) + } + if len(instanceDiff.Attributes) != 2 { + t.Fatalf("Expected 2 resource to be found, found %d", len(instanceDiff.Attributes)) + } +} diff --git a/terraform/terraform_test.go b/terraform/terraform_test.go index 2deb44153..640741e45 100644 --- a/terraform/terraform_test.go +++ b/terraform/terraform_test.go @@ -1675,10 +1675,7 @@ aws_instance.foo: const testTFPlanDiffIgnoreChangesWithFlatmaps = ` UPDATE: aws_instance.foo lst.#: "1" => "2" - lst.0: "j" => "j" lst.1: "" => "k" - set.#: "1" => "1" - set.0.a: "1" => "1" set.0.b: "" => "2" type: "" => "aws_instance" `