Open bflad opened 1 year ago
After discussions with the core team and reviewing some of the core planning logic, the framework may be able to re-implement some of the same automatic configuration <-> prior state element matching behavior on this side of the provider protocol. That may be an initial step that can be taken in this space to reduce the need for this type of developer burden.
Module version
Use-cases
After #711, the
UseStateForUnknown
plan modifier will begin raising an implementation error if it discovers during runtime that it is implemented under a list or set. This behavior was necessary to prevent cases where there could be incorrect data proposed during certain updates and to prevent Terraform errors. This catch all behavior will likely be a surprise for developers without another methodology for preserving at least some prior state values during planning.717 and #718 took an initial look at implementing a separate plan modifier which accepted identifying attributes for the list/set nested object, e.g.
This enables developers to better plan list/set element rearrangement, but understandably, this would be a little cumbersome for developers to understand when to implement the differing plan modifier as well as constructing the appropriate relative path expressions (since it needed to be very explicitly implemented and validated by the framework). Other custom plan modifiers needing prior state under a list/set would also need to reconstruct the internal logic of the new plan modifier, which would also mean that developers would need to duplicate the information when necessary, e.g.
There's also the case where there may be many identifying attributes or many attributes implementing plan modifiers that need this information. The proposed solution for #70 would also require this information to ensure that semantic equality prior state data is correct (rather than falling back to null values and potentially noisier plans).
Having a more baked-in canonical representation of this data and automatically realigning prior state before passing data to plan modifiers would simplify provider implementations. Depending on how this information is defined, it could also be used in the case of https://github.com/hashicorp/terraform/issues/30753 being exposed across the provider protocol, where Terraform could better render list/set plans where it currently needs to rely on "conventional" identifying attribute names. A #70 solution could also interrogate this information.
It is however important to ensure that provider developers still are only opting into preserving prior state values for certain attributes same as today, where the choice of
UseStateForUnknown
should be dependent on API behavior. The framework should not impose any sort of automatic behavior in that case forComputed
-only attributes.Proposal
Implement new
resource/schema.NestedAttributeObject
andresource/schema.NestedBlockObject
field for identifying attributes:This information is only required today for resource schemas, since they are the only location where there is proposed new state data on top of prior state. This should not be present on data source or provider schemas.
Given that
NestedAttributeObject
andNestedBlockObject
are already structure types instead of interface types, this implementation cannot limit the defining the new field to only list and set nested attributes and blocks. This information may be applicable to maps and single nested objects for other enhancements in the future, so having it exposed and potentially filled in by provider developers in currently extraneous cases may still serve beneficial.The choice of
[]string
instead of using apath
package based solution is because the implementation will purposefully be limited to a single nesting level (thestring
inAttributes: map[string]schema.Attribute
). Unlike certain implementation details in the prior terraform-plugin-sdk, it is not expected to introduce a synthetic syntax for constructing string-based paths in this location. If more complex schema/logic is necessary, a different solution would likely be required anyways.In
internal/fwschema
, expose newNestedAttributeObject
andNestedBlockObject
interface methods:During the
PlanResourceChange
RPC logic, the framework can then interrogate for this information to automatically realign prior state for list/set elements in the attribute plan modification logic or return null values instead. That realignment logic can implement an algorithm similar to #718 and ensure attribute plan modifiers receive the result of that realignment. This type of framework change is safe because it is opt-in for provider developers by nature of newly implementing the identifying attributes.The
UseStateForUnknown
plan modifier should be able to introduce additional validation logic where if a parent path in the request path has non-zero identifying attributes, to not raise the implementation error. The implementation error itself should be updated to mention the newIdentifyingAttributes
field to provide a helpful hint for provider developers.After all is said and done, this should then be a valid resource schema definition:
References
70
709
711
717
718