From 6f769b4264d1b7b0b24d79fa6f4a85632c73d4e7 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Sun, 24 Nov 2024 09:57:43 -0500 Subject: [PATCH] ReferenceMap.dependsOn is only used for data srcs The dependsOn method of the ReferenceMap is only used to resolve dependencies for data sources. It therefor needs to account for all possible dependencies, and cant rely on the same optimizations made for the normal AttachDependenciesTransformer. While data sources will need to continue keeping the entire dependency tree available, they obviously used far less then managed resource within normal configurations, and the data resource dependencies are not recorded to state at all. --- internal/terraform/transform_reference.go | 38 +++++++++++++---------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/internal/terraform/transform_reference.go b/internal/terraform/transform_reference.go index d120b10c2b..1fc252ce0e 100644 --- a/internal/terraform/transform_reference.go +++ b/internal/terraform/transform_reference.go @@ -340,7 +340,10 @@ func (m ReferenceMap) References(v dag.Vertex) []dag.Vertex { } // dependsOn returns the set of vertices that the given vertex refers to from -// the configured depends_on. +// the configured depends_on. This is only used to calculate depends_on for +// data sources. No other resource type changes it's behavior based on how +// dependencies are declared, hence everything else is resolved via the normal +// reference mechanism. func (m ReferenceMap) dependsOn(g *Graph, depender graphNodeDependsOn) []dag.Vertex { var res []dag.Vertex @@ -366,18 +369,20 @@ func (m ReferenceMap) dependsOn(g *Graph, depender graphNodeDependsOn) []dag.Ver } res = append(res, rv) - // Check any ancestors for transitive dependencies when we're - // not pointed directly at a resource. We can't be much more - // precise here, since in order to maintain our guarantee that data - // sources will wait for explicit dependencies, if those dependencies - // happen to be a module, output, or variable, we have to find some - // upstream managed resource in order to check for a planned - // change. + // Check any ancestors for transitive dependencies when we're not + // pointed directly at a resource. We can't be much more precise + // here, since in order to maintain our guarantee that data sources + // will wait for explicit dependencies, if those dependencies happen + // to be a module, output, or variable, we have to find some + // upstream managed resource in order to check for a planned change. + // We need to descend through all ancestors here, because data + // sources aren't just tracking this for graph edges, but rather + // they need to look for changes during the plan. if _, ok := rv.(GraphNodeConfigResource); !ok { - for _, v := range g.FirstAncestorsWith(rv, func(v dag.Vertex) bool { - return isDependableResource(v) - }) { - res = append(res, v) + for _, v := range g.Ancestors(rv) { + if isDependableResource(v) { + res = append(res, v) + } } } } @@ -445,10 +450,11 @@ func (m ReferenceMap) parentModuleDependsOn(g *Graph, depender graphNodeDependsO } } - for _, dep := range deps { - for _, v := range g.FirstAncestorsWith(dep, func(v dag.Vertex) bool { - return isDependableResource(v) - }) { + // We need to descend through all ancestors here, because data sources + // aren't just tracking this for graph edges, but rather they need to + // look for changes during the plan. + for _, v := range g.Ancestors(deps...) { + if isDependableResource(v) { res = append(res, v) } }