This commit is contained in:
Matej Risek 2026-01-30 15:02:25 +01:00
parent 8e59c3296a
commit bb8032ba0e
4 changed files with 70 additions and 7 deletions

View file

@ -0,0 +1,48 @@
package terraform
import (
"testing"
"github.com/hashicorp/terraform/internal/addrs"
provider "github.com/hashicorp/terraform/internal/providers"
"github.com/hashicorp/terraform/internal/states"
"github.com/hashicorp/terraform/internal/tfdiags"
)
func TestContextApply_TargetInstance(t *testing.T) {
testConfig := testModuleInline(t, map[string]string{
"main.tf": `
resource "test_object" "foo" {
count = 2
test_string = join("_", ["foo", count.index])
}
resource "test_object" "bar" {
count = 2
test_string = resource.test_object.foo[count.index].test_string
}
`,
})
p := simpleMockProvider()
ctx := testContext2(
t,
&ContextOpts{
Providers: map[addrs.Provider]provider.Factory{
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
},
},
)
testTarget := mustResourceInstanceAddr("test_object.bar[0]")
planOptions := DefaultPlanOpts
planOptions.Targets = []addrs.Targetable{
testTarget,
}
planOptions.SafeTargeting = true
pr, diags := ctx.Plan(testConfig, states.NewState(), planOptions)
tfdiags.AssertNoErrors(t, diags)
_ = pr.Changes.Resources
t.Log("test")
}

View file

@ -67,6 +67,8 @@ type PlanOpts struct {
// warnings as part of the planning result.
Targets []addrs.Targetable
SafeTargeting bool
// ActionTargets represents the actions that should be triggered by this
// execution. This is incompatible with the `Targets` attribute, only one
// can be set. Also, Mode must be plans.RefreshOnly when using
@ -1005,6 +1007,7 @@ func (c *Context) planGraph(config *configs.Config, prevRunState *states.State,
ExternalProviderConfigs: externalProviderConfigs,
Plugins: c.plugins,
Targets: opts.Targets,
SafeTargeting: opts.SafeTargeting,
ForceReplace: opts.ForceReplace,
skipRefresh: opts.SkipRefresh,
preDestroyRefresh: opts.PreDestroyRefresh,

View file

@ -132,6 +132,9 @@ type PlanGraphBuilder struct {
// or test runtimes, where the root modules as Terraform sees them aren't
// the actual root modules.
AllowRootEphemeralOutputs bool
// TODO: Add comment
SafeTargeting bool
}
// See GraphBuilder
@ -303,6 +306,10 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer {
// Target
&TargetsTransformer{Targets: b.Targets},
// TODO_SAMS: Check whether we can create a dummy safe target transformer
// which checks references and trims down the produce of targetsTransformer
// down to what instances are actually targeted by the defined target.
// Filter the graph to only include nodes that are relevant to the query operation.
&QueryTransformer{queryPlan: b.queryPlan, validate: b.Operation == walkValidate},

View file

@ -197,13 +197,18 @@ func (t *TargetsTransformer) nodeIsTarget(v dag.Vertex, targets []addrs.Targetab
return false
}
// addVertexDependenciesToTargetedNodes adds dependencies of the targeted vertex to the
// targetedNodes set. This includes all ancestors in the graph.
// It also includes all action trigger nodes in the graph. Actions are planned after the
// triggering node has planned so that we can ensure the actions are only planned if the triggering
// resource has an action (Create / Update) corresponding to one of the events in the action trigger
// blocks event list.
func (t *TargetsTransformer) addVertexDependenciesToTargetedNodes(g *Graph, v dag.Vertex, targetedNodes dag.Set, addrs []addrs.Targetable) {
// addVertexDependenciesToTargetedNodes adds dependencies of the targeted vertex
// to the targetedNodes set. This includes all ancestors in the graph.
// It also includes all action trigger nodes in the graph. Actions are planned
// after the triggering node has planned so that we can ensure the actions are
// only planned if the triggering resource has an action (Create / Update)
// corresponding to one of the events in the action trigger blocks event list.
func (t *TargetsTransformer) addVertexDependenciesToTargetedNodes(
g *Graph,
v dag.Vertex,
targetedNodes dag.Set,
addrs []addrs.Targetable,
) {
if targetedNodes.Include(v) {
return
}