Files
opentf/internal/engine/planning/execgraph_managed.go
Martin Atkins fdd992cfa7 planning: Build manage resource instance execgraph from planned change
The temporary placeholder code was relying only on the
DesiredResourceInstance object, which was good enough for proving that this
could work at all and had the advantage of being a new-style model with
new-style representations of the provider instance address and the other
resource instances that the desired object depends on.

But that isn't enough information to plan anything other than "create"
changes, so now we'll switch to using plans.ResourceInstanceChange as the
main input to the execgraph building logic, even though for now that means
we need to carry a few other values alongside it to compensate for the
shortcomings of that old model designed for the old language runtime.

So far this doesn't actually change what we do in response to the change
so it still only supports "create" changes. In future commits we'll make
the execGraphBuilder method construct different shapes of graph depending
on which change action was planned.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-02-09 07:35:50 -08:00

68 lines
2.8 KiB
Go

// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package planning
import (
"github.com/opentofu/opentofu/internal/addrs"
"github.com/opentofu/opentofu/internal/engine/internal/exec"
"github.com/opentofu/opentofu/internal/engine/internal/execgraph"
"github.com/opentofu/opentofu/internal/plans"
)
////////////////////////////////////////////////////////////////////////////////
// This file contains methods of [execGraphBuilder] that are related to the
// parts of an execution graph that deal with resource instances of mode
// [addrs.ManagedResourceMode] in particular.
////////////////////////////////////////////////////////////////////////////////
// ManagedResourceSubgraph adds graph nodes needed to apply changes for a
// managed resource instance, and returns what should be used as its final
// result to propagate into to downstream references.
//
// TODO: This is definitely not sufficient for the full complexity of all of the
// different ways managed resources can potentially need to be handled in an
// execution graph. It's just a simple placeholder adapted from code that was
// originally written inline in [planGlue.planDesiredManagedResourceInstance]
// just to preserve the existing functionality for now until we design a more
// complete approach in later work.
func (b *execGraphBuilder) ManagedResourceInstanceSubgraph(
plannedChange *plans.ResourceInstanceChange,
providerClientRef execgraph.ResultRef[*exec.ProviderClient],
requiredResourceInstances addrs.Set[addrs.AbsResourceInstance],
) execgraph.ResourceInstanceResultRef {
b.mu.Lock()
defer b.mu.Unlock()
// We need to explicitly model our dependency on any upstream resource
// instances in the resource instance graph. These don't naturally emerge
// from the data flow because these results are intermediated through the
// evaluator, which indirectly incorporates the results into the
// desiredInstRef result we'll build below.
dependencyWaiter, closeDependencyAfter := b.waiterForResourceInstances(requiredResourceInstances.All())
// FIXME: If this is one of the "replace" actions then we need to generate
// a more complex graph that has two pairs of "final plan" and "apply".
instAddrRef := b.lower.ConstantResourceInstAddr(plannedChange.Addr)
priorStateRef := b.lower.ResourceInstancePrior(instAddrRef)
plannedValRef := b.lower.ConstantValue(plannedChange.After)
desiredInstRef := b.lower.ResourceInstanceDesired(instAddrRef, dependencyWaiter)
finalPlanRef := b.lower.ManagedFinalPlan(
desiredInstRef,
priorStateRef,
plannedValRef,
providerClientRef,
)
finalResultRef := b.lower.ManagedApply(
finalPlanRef,
execgraph.NilResultRef[*exec.ResourceInstanceObject](),
providerClientRef,
)
closeDependencyAfter(finalResultRef)
return finalResultRef
}