From 64eb5f732c440a5c912cd01502dda15d2dbecf67 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Wed, 12 Sep 2018 16:56:06 -0700 Subject: [PATCH] core: NodeApplyableResource only depends on count and for_each Only the count and for_each expressions are evaluated by this node type, so it doesn't need to declare dependencies for any other refs in the configuration body. Using this more refined set of dependencies means we can avoid graph cycles in the case where one instance of a resource refers to another instance of the same resource. We'll still get cycles if count or for_each self-reference, but that's forbidden anyway (caught during validate) and makes sense because those two are whole-resource-level config rather than per-instance config. --- terraform/node_resource_apply.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/terraform/node_resource_apply.go b/terraform/node_resource_apply.go index e9d84a2f3..3e2fff3a0 100644 --- a/terraform/node_resource_apply.go +++ b/terraform/node_resource_apply.go @@ -2,6 +2,10 @@ package terraform import ( "log" + + "github.com/hashicorp/terraform/addrs" + "github.com/hashicorp/terraform/dag" + "github.com/hashicorp/terraform/lang" ) // NodeApplyableResource represents a resource that is "applyable": @@ -21,12 +25,32 @@ var ( _ GraphNodeEvalable = (*NodeApplyableResource)(nil) _ GraphNodeProviderConsumer = (*NodeApplyableResource)(nil) _ GraphNodeAttachResourceConfig = (*NodeApplyableResource)(nil) + _ GraphNodeReferencer = (*NodeApplyableResource)(nil) ) func (n *NodeApplyableResource) Name() string { return n.NodeAbstractResource.Name() + " (prepare state)" } +func (n *NodeApplyableResource) References() []*addrs.Reference { + if n.Config == nil { + log.Printf("[WARN] NodeApplyableResource %q: no configuration, so can't determine References", dag.VertexName(n)) + return nil + } + + var result []*addrs.Reference + + // Since this node type only updates resource-level metadata, we only + // need to worry about the parts of the configuration that affect + // our "each mode": the count and for_each meta-arguments. + refs, _ := lang.ReferencesInExpr(n.Config.Count) + result = append(result, refs...) + refs, _ = lang.ReferencesInExpr(n.Config.ForEach) + result = append(result, refs...) + + return result +} + // GraphNodeEvalable func (n *NodeApplyableResource) EvalTree() EvalNode { addr := n.ResourceAddr()