diff --git a/internal/planmodifiers/attribute.go b/internal/planmodifiers/attribute.go index afe34118..43d0e550 100644 --- a/internal/planmodifiers/attribute.go +++ b/internal/planmodifiers/attribute.go @@ -168,26 +168,54 @@ func (r requiresReplaceIfValuesNotNullModifier) Modify(ctx context.Context, req return } - attrConfig := req.AttributeConfig + configMap, ok := req.AttributeConfig.(types.Map) + if !ok { + return + } - m, ok := attrConfig.(types.Map) + stateMap, ok := req.AttributeState.(types.Map) if !ok { return } replace := false - for _, v := range m.Elems { - if v.IsNull() && !v.IsUnknown() { + additionalElems := map[string]attr.Value{} + + for k, v := range configMap.Elems { + if _, ok := stateMap.Elems[k]; !ok { + if !v.IsNull() || v.IsUnknown() { + replace = true + break + } continue } - replace = true + if stateMap.Elems[k] != configMap.Elems[k] { + replace = true + break + } + + if v.IsNull() && !v.IsUnknown() { + additionalElems[k] = v + } } if replace { resp.RequiresReplace = true + return } + + respPlan := resp.AttributePlan + + pm, ok := respPlan.(types.Map) + if ok { + for k, v := range additionalElems { + pm.Elems[k] = v + } + } + + resp.AttributePlan = pm } // Description returns a human-readable description of the plan modifier. diff --git a/internal/provider/resource_integer.go b/internal/provider/resource_integer.go index 0502d5c0..d6e3d2a5 100644 --- a/internal/provider/resource_integer.go +++ b/internal/provider/resource_integer.go @@ -63,11 +63,17 @@ func (r *integerResourceType) GetSchema(context.Context) (tfsdk.Schema, diag.Dia Description: "The random integer result.", Type: types.Int64Type, Computed: true, + PlanModifiers: []tfsdk.AttributePlanModifier{ + resource.UseStateForUnknown(), + }, }, "id": { Description: "The string representation of the integer result.", Type: types.StringType, Computed: true, + PlanModifiers: []tfsdk.AttributePlanModifier{ + resource.UseStateForUnknown(), + }, }, }, }, nil @@ -136,6 +142,7 @@ func (r *integerResource) Read(ctx context.Context, req resource.ReadRequest, re // Update is intentionally left blank as all required and optional attributes force replacement of the resource // through the RequiresReplace AttributePlanModifier. func (r *integerResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + resp.State = tfsdk.State(req.Plan) } // Delete does not need to explicitly call resp.State.RemoveResource() as this is automatically handled by the