mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-25 16:31:10 -06:00
64eb5f732c
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.
72 lines
2.2 KiB
Go
72 lines
2.2 KiB
Go
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":
|
|
// it may need to have its record in the state adjusted to match configuration.
|
|
//
|
|
// Unlike in the plan walk, this resource node does not DynamicExpand. Instead,
|
|
// it should be inserted into the same graph as any instances of the nodes
|
|
// with dependency edges ensuring that the resource is evaluated before any
|
|
// of its instances, which will turn ensure that the whole-resource record
|
|
// in the state is suitably prepared to receive any updates to instances.
|
|
type NodeApplyableResource struct {
|
|
*NodeAbstractResource
|
|
}
|
|
|
|
var (
|
|
_ GraphNodeResource = (*NodeApplyableResource)(nil)
|
|
_ 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()
|
|
config := n.Config
|
|
providerAddr := n.ResolvedProvider
|
|
|
|
if config == nil {
|
|
// Nothing to do, then.
|
|
log.Printf("[TRACE] NodeApplyableResource: no configuration present for %s", addr)
|
|
return &EvalNoop{}
|
|
}
|
|
|
|
return &EvalWriteResourceState{
|
|
Addr: addr.Resource,
|
|
Config: config,
|
|
ProviderAddr: providerAddr,
|
|
}
|
|
}
|