Files
opentf/internal/lang/eval/provider_instance.go
Martin Atkins 22e5168af1 planning: Split responsibility for provider instance execgraph building
Previously we did _all_ of the work related to preparing execgraph items
for provider instances as a side-effect of the ProviderInstance method
of execGraphBuilder.

Now we'll split it into two parts: the first time we encounter each
provider instance during planning we'll proactively gather its dependencies
and stash them in the graph builder. However, we'll still wait until the
first request for the execution subgraph of a provider instance before
we actually insert that into the graph, because that then effectively
excludes from the apply phase any provider instances that aren't needed for
the actual planned side-effects. In particular, if all of the resource
instances belonging to a provider instance turn out to have "no-op" plans
then that provider instance won't appear in the execution graph at all.

An earlier draft of this change did the first dependency capturing step via
a new method of planGlue called by the evaluator, but after writing that
I found it unfortunate to introduce yet another inversion of control
situation where readers of the code just need to know and trust that the
evaluator will call things in a correct order -- there's already enough
of that for resource instances -- and so I settled on the compromise of
having the ensureProviderInstanceDependencies calls happen as part of the
linear code for handling each resource instance object, which makes it far
easier for a future maintainer to verify that we're upholding the contract
of calling ensureProviderInstanceDependencies before asking for an
execgraph result, while still allowing us to handle that step generically
instead of duplicating it into each resource-mode-specific handler.

While working on this I noticed a slight flaw in our initial approach to
handling ephemeral resource instances in the execution graph, which is
described inline as a comment in planDesiredEphemeralResourceInstance.
We'll need to think about that some more and deal with it in a future
commit.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-02-05 13:06:39 -08:00

39 lines
1.5 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 eval
import (
"github.com/zclconf/go-cty/cty"
"github.com/opentofu/opentofu/internal/addrs"
)
// ProviderInstanceConfig provides the information needed to either instantiate
// and configure a provider instance for the first time or to find a
// previously-configured object for the same provider instance.
type ProviderInstanceConfig struct {
// Addr is the address for the provider instance, unique across the whole
// configuration.
//
// This is a good key to use for a table of previously-configured provider
// objects.
Addr addrs.AbsProviderInstanceCorrect
// ConfigVal is the configuration value to send to the provider when
// configuring it. The relationship between Addr and ConfigVal is
// guaranteed to be consistent for all ProviderInstanceConfig objects
// produced through a particular [ConfigInstance], and so it's safe
// to reuse a previously-configured provider (and thus ignore ConfigVal)
// when the address matches.
ConfigVal cty.Value
// RequiredResourceInstances is a set of all of the resource instances
// that somehow contribute to the configuration of the resource instance,
// and so which must therefore have any changes applied before evaluating
// the configuration for this provider instance during the apply phase.
RequiredResourceInstances addrs.Set[addrs.AbsResourceInstance]
}