diff --git a/helper/schema/resource.go b/helper/schema/resource.go index 571fe18a60..8b3e53ad33 100644 --- a/helper/schema/resource.go +++ b/helper/schema/resource.go @@ -244,7 +244,20 @@ func (r *Resource) InternalValidate(topSchemaMap schemaMap) error { return fmt.Errorf( "No Update defined, must set ForceNew on: %#v", nonForceNewAttrs) } + } else { + nonUpdateableAttrs := make([]string, 0) + for k, v := range r.Schema { + if v.ForceNew || (v.Computed && !v.Optional) { + nonUpdateableAttrs = append(nonUpdateableAttrs, k) + } + } + updateableAttrs := len(r.Schema) - len(nonUpdateableAttrs) + if updateableAttrs == 0 { + return fmt.Errorf( + "All fields are ForceNew or Computed w/out Optional, Update is superfluous") + } } + tsm = schemaMap(r.Schema) } diff --git a/helper/schema/resource_test.go b/helper/schema/resource_test.go index e35979eb2f..3604322e75 100644 --- a/helper/schema/resource_test.go +++ b/helper/schema/resource_test.go @@ -335,6 +335,36 @@ func TestResourceInternalValidate(t *testing.T) { }, true, }, + + // Update undefined for non-ForceNew field + { + &Resource{ + Create: func(d *ResourceData, meta interface{}) error { return nil }, + Schema: map[string]*Schema{ + "boo": &Schema{ + Type: TypeInt, + Optional: true, + }, + }, + }, + true, + }, + + // Update defined for ForceNew field + { + &Resource{ + Create: func(d *ResourceData, meta interface{}) error { return nil }, + Update: func(d *ResourceData, meta interface{}) error { return nil }, + Schema: map[string]*Schema{ + "goo": &Schema{ + Type: TypeInt, + Optional: true, + ForceNew: true, + }, + }, + }, + true, + }, } for i, tc := range cases {