terraform: Write state if sensitivity changes
When applying, we return early if only sensitivity changed between the before and after values of the changeset. This avoids unnecessarily invoking the provider. Previously, we did not write the new value for a resource to the state when this happened. The result was a permanent diff for resource updates which only change sensitivity, as the apply step is skipped and the state is unchanged. This commit adds a state write to this shortcut return path, and fixes a test for this exact case which was accidentally relying on a value diff caused by an incorrect manual state value.
This commit is contained in:
parent
2ce71ab43c
commit
50f4d79867
|
@ -12049,7 +12049,7 @@ resource "test_resource" "foo" {
|
|||
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
|
||||
&states.ResourceInstanceObjectSrc{
|
||||
Status: states.ObjectReady,
|
||||
AttrsJSON: []byte(`{"id":"foo", "value":"hello"}`),
|
||||
AttrsJSON: []byte(`{"id":"foo", "value":"hello", "network_interface":[]}`),
|
||||
// No AttrSensitivePaths present
|
||||
},
|
||||
addrs.AbsProviderConfig{
|
||||
|
@ -12070,6 +12070,9 @@ resource "test_resource" "foo" {
|
|||
|
||||
fooState := state.ResourceInstance(addr)
|
||||
|
||||
if len(fooState.Current.AttrSensitivePaths) != 1 {
|
||||
t.Fatalf("wrong number of sensitive paths, expected 1, got, %v", len(fooState.Current.AttrSensitivePaths))
|
||||
}
|
||||
got := fooState.Current.AttrSensitivePaths[0]
|
||||
want := cty.PathValueMarks{
|
||||
Path: cty.GetAttrPath("value"),
|
||||
|
|
|
@ -118,10 +118,26 @@ func (n *EvalApply) Eval(ctx EvalContext) tfdiags.Diagnostics {
|
|||
|
||||
// If we have an Update action, our before and after values are equal,
|
||||
// and only differ on their sensitivity, the newVal is the after val
|
||||
// and we should not communicate with the provider or perform further action.
|
||||
// and we should not communicate with the provider. We do need to update
|
||||
// the state with this new value, to ensure the sensitivity change is
|
||||
// persisted.
|
||||
eqV := unmarkedBefore.Equals(unmarkedAfter)
|
||||
eq := eqV.IsKnown() && eqV.True()
|
||||
if change.Action == plans.Update && eq && !reflect.DeepEqual(beforePaths, afterPaths) {
|
||||
// Copy the previous state, changing only the value
|
||||
newState := &states.ResourceInstanceObject{
|
||||
CreateBeforeDestroy: state.CreateBeforeDestroy,
|
||||
Dependencies: state.Dependencies,
|
||||
Private: state.Private,
|
||||
Status: state.Status,
|
||||
Value: change.After,
|
||||
}
|
||||
|
||||
// Write the final state
|
||||
if n.Output != nil {
|
||||
*n.Output = newState
|
||||
}
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue