diff --git a/helper/schema/resource.go b/helper/schema/resource.go index a26dfc9f88..d96bbcfde2 100644 --- a/helper/schema/resource.go +++ b/helper/schema/resource.go @@ -155,6 +155,27 @@ type Resource struct { Timeouts *ResourceTimeout } +// ShimInstanceStateFromValue converts a cty.Value to a +// terraform.InstanceState. +func (r *Resource) ShimInstanceStateFromValue(state cty.Value) (*terraform.InstanceState, error) { + // Get the raw shimmed value. While this is correct, the set hashes don't + // match those from the Schema. + s := terraform.NewInstanceStateShimmedFromValue(state, r.SchemaVersion) + + // We now rebuild the state through the ResourceData, so that the set indexes + // match what helper/schema expects. + data, err := schemaMap(r.Schema).Data(s, nil) + if err != nil { + return nil, err + } + + s = data.State() + if s == nil { + s = &terraform.InstanceState{} + } + return s, nil +} + // See Resource documentation. type CreateFunc func(*ResourceData, interface{}) error @@ -550,8 +571,7 @@ func (r *Resource) upgradeState(s *terraform.InstanceState, meta interface{}) (* return nil, err } - s = InstanceStateFromStateValue(stateVal, r.SchemaVersion) - return s, nil + return r.ShimInstanceStateFromValue(stateVal) } // InternalValidate should be called to validate the structure diff --git a/helper/schema/shims.go b/helper/schema/shims.go index 52ae7d7446..5b978ee8e2 100644 --- a/helper/schema/shims.go +++ b/helper/schema/shims.go @@ -23,7 +23,7 @@ func DiffFromValues(prior, planned cty.Value, res *Resource) (*terraform.Instanc // only needs to be created for the apply operation, and any customizations // have already been done. func diffFromValues(prior, planned cty.Value, res *Resource, cust CustomizeDiffFunc) (*terraform.InstanceDiff, error) { - instanceState := InstanceStateFromStateValue(prior, res.SchemaVersion) + instanceState := terraform.NewInstanceStateShimmedFromValue(prior, res.SchemaVersion) configSchema := res.CoreConfigSchema() @@ -85,11 +85,3 @@ func JSONMapToStateValue(m map[string]interface{}, block *configschema.Block) (c func StateValueFromInstanceState(is *terraform.InstanceState, ty cty.Type) (cty.Value, error) { return is.AttrsAsObjectValue(ty) } - -// InstanceStateFromStateValue converts a cty.Value to a -// terraform.InstanceState. This function requires the schema version used by -// the provider, because the legacy providers used the private Meta data in the -// InstanceState to store the schema version. -func InstanceStateFromStateValue(state cty.Value, schemaVersion int) *terraform.InstanceState { - return terraform.NewInstanceStateShimmedFromValue(state, schemaVersion) -}