github.com/hashicorp/terraform-plugin-sdk@v1.17.2/terraform/node_resource_apply.go (about)

     1  package terraform
     2  
     3  import (
     4  	"log"
     5  
     6  	"github.com/hashicorp/terraform-plugin-sdk/internal/addrs"
     7  	"github.com/hashicorp/terraform-plugin-sdk/internal/dag"
     8  	"github.com/hashicorp/terraform-plugin-sdk/internal/lang"
     9  )
    10  
    11  // NodeApplyableResource represents a resource that is "applyable":
    12  // it may need to have its record in the state adjusted to match configuration.
    13  //
    14  // Unlike in the plan walk, this resource node does not DynamicExpand. Instead,
    15  // it should be inserted into the same graph as any instances of the nodes
    16  // with dependency edges ensuring that the resource is evaluated before any
    17  // of its instances, which will turn ensure that the whole-resource record
    18  // in the state is suitably prepared to receive any updates to instances.
    19  type NodeApplyableResource struct {
    20  	*NodeAbstractResource
    21  }
    22  
    23  var (
    24  	_ GraphNodeResource             = (*NodeApplyableResource)(nil)
    25  	_ GraphNodeEvalable             = (*NodeApplyableResource)(nil)
    26  	_ GraphNodeProviderConsumer     = (*NodeApplyableResource)(nil)
    27  	_ GraphNodeAttachResourceConfig = (*NodeApplyableResource)(nil)
    28  	_ GraphNodeReferencer           = (*NodeApplyableResource)(nil)
    29  )
    30  
    31  func (n *NodeApplyableResource) Name() string {
    32  	return n.NodeAbstractResource.Name() + " (prepare state)"
    33  }
    34  
    35  func (n *NodeApplyableResource) References() []*addrs.Reference {
    36  	if n.Config == nil {
    37  		log.Printf("[WARN] NodeApplyableResource %q: no configuration, so can't determine References", dag.VertexName(n))
    38  		return nil
    39  	}
    40  
    41  	var result []*addrs.Reference
    42  
    43  	// Since this node type only updates resource-level metadata, we only
    44  	// need to worry about the parts of the configuration that affect
    45  	// our "each mode": the count and for_each meta-arguments.
    46  	refs, _ := lang.ReferencesInExpr(n.Config.Count)
    47  	result = append(result, refs...)
    48  	refs, _ = lang.ReferencesInExpr(n.Config.ForEach)
    49  	result = append(result, refs...)
    50  
    51  	return result
    52  }
    53  
    54  // GraphNodeEvalable
    55  func (n *NodeApplyableResource) EvalTree() EvalNode {
    56  	addr := n.ResourceAddr()
    57  	config := n.Config
    58  	providerAddr := n.ResolvedProvider
    59  
    60  	if config == nil {
    61  		// Nothing to do, then.
    62  		log.Printf("[TRACE] NodeApplyableResource: no configuration present for %s", addr)
    63  		return &EvalNoop{}
    64  	}
    65  
    66  	return &EvalWriteResourceState{
    67  		Addr:         addr.Resource,
    68  		Config:       config,
    69  		ProviderAddr: providerAddr,
    70  	}
    71  }