Commit Graph

3 Commits

Author SHA1 Message Date
Martin Atkins
7100a94c26 resources: Ignore spurious RequiresReplace from PlanResourceChange
Unfortunately some existing providers suriously report RequiresReplace
paths when they are planning create and/or delete changes, so we'll need to
just quietly ignore them rather than generating a user-facing error about
it.

In practice ignoring these in these cases doesn't really do any harm, since
RequiresReplace is only relevant in causing us to reinterpret an "update"
into a "replace". But to keep the handling of this quirk centralized, we
explicitly throw away spurious paths so that the rest of the system can
safely assume that this field will be populated only when some action must
be taken based on it.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-03-06 12:02:34 -08:00
Martin Atkins
21907c5636 resources: Don't allow RequiresReplace for non-update changes
Previously we had this check in the apply engine because it was making
sure that the decomposed parts of a "replace" don't themselves call for
a replace action, but it's a general rule that RequiresReplace is not
meaningful unless there's both a current and a desired object to compare,
so this moves that check into the "resources" package as a general rule.

A future commit will rely on this once the planning engine correctly
handles "replace" actions by asking the provider to re-plan as if the
old object didn't exist, in order to predict the "create" part of the
replace action.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-03-05 06:55:47 -08:00
Martin Atkins
2585a63df0 resources: A new package for resource-related operations
The original motivation here was to implement the special case of making
a synthetic plan without calling into the provider when the desired state
is absent and the provider hasn't opted in to planning to destroy objects.
This case needs to be opted in because older providers will crash if asked
to plan with the config value or proposed value set to null.

However, there was already far too much code duplicated across both the
planning engine and the apply engine's "final plan" operation, and so this
seemed like a good prompt to finally resolve those TODO comments and factor
out the shared planning logic into a separate place that both can depend
on.

The new package "resources" is intended to grow into the home for all of
these resource-related operations that each wrap a lower-level provider
call but also perform preparation or followup actions such as making sure
the provider's response is valid according to the requirements of the
plugin protocol.

For now it only includes config validation and planning for managed
resources, but is designed to grow to include other similar operations in
future. The most likely next step is to add a method for applying a
previously-created plan, which would replace a bunch of the code in the
apply engine's implementation of the "ManagedApply" operation.

Currently the way this integrates with the rest of the provider-related
infrastructure is a little awkward. We can hopefully improve on that in
future, but for now the priority was to avoid this becoming yet another
sprawling architecture change that would be hard to review. Once we feel
like we've achieved the "walking skeleton" milestone for the new runtime
we can think about how we want to tidy up the rough edges between the
different components of this new design.

As has become tradition for these new codepaths, this is designed to be
independently testable but not yet actually tested because we want to wait
and see how all of this code settles before we start writing tests that
would then make it harder to refactor as we learn more.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-03-04 10:30:11 -08:00