Commit Graph

12 Commits

Author SHA1 Message Date
Martin Atkins
ac9a26d5b9 exec: ManagedDepose and ManagedChangeAddr take object as operand
These both effectively had the behavior of ResourceInstancePrior embedded
in them, reading something from the state and change its address as a
single compound operation.

In the case of ManagedDepose we need to split these up for the
CreateThenDestroy variant of "replace", because we want to make sure the
final plans are valid before we depose anything and we need the prior state
to produce the final plan. (Actually using that will follow in a subsequent
commit.)

This isn't actually necessary for ManageChangeAddr, but splitting it keeps
these two operations consistent in how they interact with the rest of the
operations.

Due to how the existing states.SyncState works we're not actually making
good use of the data flow of these objects right now, but in a future world
where we're no longer using the old state models hopefully the state API
will switch to an approach that's more aligned with how the execgraph
operations are modeled.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-02-10 07:07:01 -08:00
Martin Atkins
a1aec0e920 execgraph: opManagedChangeAddr for handling "moved" blocks
Whenever we plan for a resource instance object to switch from one instance
address to another, we'll use this new op instead of ResourceInstancePrior
to perform the state modification needed for the rename before returning
the updated object.

We combine the rename and the state read into a single operation to ensure
that they can appear to happen atomically as far as the rest of the system
is concerned, so that there's no interim state where either both or neither
of the address bindings are present in the state.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-02-09 07:35:50 -08:00
Christian Mesh
8ce780b4e0 engine/ephemeral: Wire together basic ephemeral functionality (#3710)
Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
2026-02-04 16:44:20 -05:00
Martin Atkins
478d86d214 engine/applying: Use "apply phase" prefix in trace logs
These were previously using "applying:" as the common prefix, but I found
that confusing in practice because only the "ManagedApply" operation is
_actually_ applying changes.

Instead then we'll identify these trace logs as belonging to the apply
phase as a whole, to try to be a little clearer about what's going on.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-02-02 10:27:07 -08:00
Martin Atkins
0e422bc546 engine/applying: Managed resource plan and apply
Here we ask the provider to produce a plan based on the finalized
configuration taken from the "desired state", and return it as a final plan
object only if the provider request succeeds and returns something that is
valid under our usual plan consistency rules.

We then ask the provider to apply that plan, and deal with whatever it
returns. The apply part of this is not so complete yet, but there's enough
here to handle the happy path where the operation succeeds and the provider
returns something valid.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-02-02 10:27:07 -08:00
Martin Atkins
25d910c2ef engine/applying: Log the provider instance for each resource instance
This'll make it clearer which provider we're using to ask each question,
without making a human reader try to work backwards through the execution
graph data flow.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-02-02 10:27:07 -08:00
Martin Atkins
9b35d84dd1 engine/applying: Track grapheval/workgraph requests
There is currently a bug in the apply engine that's causing a
self-dependency error during promise resolution, which was a good reminder
that we'd not previously finished connecting all of the parts to be able
to unwind such problems into a useful error message.

Due to how the work is split between the apply engine, the evaluator, and
the execgraph package it takes some awkward back-and-forth to get all of
the needed information together into one place. This compromise aims to
do as little work as possible in the happy path and defer more expensive
analysis until we actually know we're going to report an error message.

In this case we can't really avoid proactively collecting the request IDs
because we don't know ahead of time what (if anything) will be involved in
a promise error, but only when actually generating an error message will
we dig into the original source execution graph to find out what each of
the affected requests was actually trying to do and construct a
human-friendly summary of each one.

This was a bit of a side-quest relative to the current goal of just getting
things basically working with a simple configuration, but this is useful
in figuring out what's going on with the current bug (which will be fixed
in a future commit) and will probably be useful when dealing with future
bugs too.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-02-02 10:27:07 -08:00
Martin Atkins
c1690a0ccf exec: ResourceInstanceObject represents an object and its address
During execution graph processing we need to carry addressing information
along with objects so that we can model changes of address as data flow
rather than as modifications to global mutable state.

In previous commits we arranged for other relevant types to track this
information, but the representation of a resource instance object was not
included because that was a messier change to wire in. This commit deals
with that mess: it introduces exec.ResourceInstanceObject to associate a
resource instance object with addressing information, and then adopts that
as the canonical representation of a "resource instance object result"
throughout all of the execution graph operations.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-02-02 10:27:07 -08:00
Martin Atkins
2af3eff7b5 execgraph: A more complete set of supported opcodes
The first pass of this was mainly just to illustrate how the overall model
of execution graphs might work, using just a few "obvious" opcodes as a
placeholder for the full set.

Now that we're making some progress towards getting this to actually work
as part of a real apply phase this reworks the set of opcodes in a few
different ways:

- Some concepts that were previously handled as special cases in the
  execution graph executor are now just regular operations. The general
  idea here is that anything that is fallible and/or has externally-visible
  side-effects should be modelled as an operation.
- The set of supported operations for managed resources should now be
  complete enough to describe all of the different series of steps that
  result from different kinds of plan. In particular, this now has the
  building blocks needed to implement a "create then destroy" replace
  operation, which includes the step of "deposing" the original object
  until we've actually destroyed it.
- The new package "exec" contains vocabulary types for data flowing between
  operations, and an interface representing the operations themselves.
  The types in this package allow us to carry addressing information along
  with objects that would not normally carry that directly, which means
  we don't need to propagate that address information around the execution
  graph through side-channels.

  (A notable gap as of this commit is that resource instance objects don't
  have address information yet. That'll follow in a subsequent commit just
  because it requires some further rejiggering.)
- The interface implemented by the applying engine and provided to the
  execution graph now more directly relates to the operations described
  in the execution graph, so that it's considerably easier to follow how
  the graph built by the planning phase corresponds to calls into that
  interface in the applying phase.
- We're starting to consider OpenTofu's own tracking identifiers for
  resource instances as separate from how providers refer to their resource
  types, just so that the opinions about how those two related can be
  more centralized in future, vs. the traditional runtime where the rules
  about how those related tend to be spread haphazardly throughout the
  codebase, and in particular implementing migration between resource
  types was traditionally challenging because it creates a situation where
  the desired resource type and the current resource type _intentionally_
  differ.

This is a large commit because the execution graph concepts are
cross-cutting between the plan and apply engines, but outside of execgraph
the changes here are mainly focused on just making things compile again
with as little change as possible, and then subsequent commits will get
the other packages into a better working shape again.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-02-02 10:27:07 -08:00
Martin Atkins
2e09323694 engine/applying: First somewhat-working implementation
This is just enough to connect all of the apply engine parts together into
a functional whole which can at least attempt to apply a plan. There are
various gaps here that make this not fully work in practice, but the goal
of this commit is to just get all of the components connected together in
their current form and then subsequent commits will gradually build on this
to make it work better.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-01-16 09:50:36 -08:00
Martin Atkins
4641cb8b2f engine/applying: Execution graph compilation and other stubbing
This is just some initial sketching of how the applying package might do
its work. Not yet finished, and I'm expecting to change about the
execution graph operations in future commits now that the main plan/apply
flow is plumbed in and so it's easier to test things end-to-end.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-01-16 09:50:36 -08:00
Martin Atkins
d8d21619a4 backend/local: Initial setup for the new runtime's "apply" command
This is just enough to get the plan object and check that it has the
execution graph field populated, and to load the configuration. More to
come in later commits.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-01-16 09:50:36 -08:00