diff --git a/helper/diff/resource_builder.go b/helper/diff/resource_builder.go index 53f1a6839..206f9875d 100644 --- a/helper/diff/resource_builder.go +++ b/helper/diff/resource_builder.go @@ -45,6 +45,10 @@ type ResourceBuilder struct { // resource creation time. ComputedAttrs []string + // ComputedAttrsUpdate are the attributes that are computed + // at resource update time (this includes creation). + ComputedAttrsUpdate []string + // PreProcess is a mapping of exact keys that are sent through // a pre-processor before comparing values. The original value will // be put in the "NewExtra" field of the diff. @@ -185,6 +189,23 @@ func (b *ResourceBuilder) Diff( } } + // If we're changing anything, then mark the updated + // attributes. + if len(attrs) > 0 { + for _, k := range b.ComputedAttrsUpdate { + if _, ok := attrs[k]; ok { + continue + } + + old := s.Attributes[k] + attrs[k] = &terraform.ResourceAttrDiff{ + Old: old, + NewComputed: true, + Type: terraform.DiffAttrOutput, + } + } + } + // Build our resulting diff if we had attributes change var result *terraform.ResourceDiff if len(attrs) > 0 { diff --git a/helper/diff/resource_builder_test.go b/helper/diff/resource_builder_test.go index 8f2a99c86..4b1f87594 100644 --- a/helper/diff/resource_builder_test.go +++ b/helper/diff/resource_builder_test.go @@ -170,6 +170,38 @@ func TestResourceBuilder_complexReplace(t *testing.T) { } } +func TestResourceBuilder_computedAttrsUpdate(t *testing.T) { + rb := &ResourceBuilder{ + Attrs: map[string]AttrType{ + "foo": AttrTypeUpdate, + }, + ComputedAttrsUpdate: []string{ + "bar", + }, + } + + state := &terraform.ResourceState{ + Attributes: map[string]string{"foo": "foo"}, + } + c := testConfig(t, map[string]interface{}{ + "foo": "bar", + }, nil) + + diff, err := rb.Diff(state, c) + if err != nil { + t.Fatalf("err: %s", err) + } + if diff == nil { + t.Fatal("diff shold not be nil") + } + + actual := testResourceDiffStr(diff) + expected := testRBComputedAttrUpdate + if actual != expected { + t.Fatalf("bad: %s", actual) + } +} + func TestResourceBuilder_new(t *testing.T) { rb := &ResourceBuilder{ Attrs: map[string]AttrType{ @@ -407,6 +439,11 @@ const testRBComplexReplaceDiff = `UPDATE IN listener.0.value: "" => "50" ` +const testRBComputedAttrUpdate = `UPDATE + OUT bar: "" => "" + IN foo: "foo" => "bar" +` + const testRBNewDiff = `UPDATE IN foo: "" => "bar" OUT private_ip: "" => ""