github.com/hashicorp/terraform-plugin-sdk@v1.17.2/terraform/graph_builder_eval.go (about) 1 package terraform 2 3 import ( 4 "github.com/hashicorp/terraform-plugin-sdk/internal/addrs" 5 "github.com/hashicorp/terraform-plugin-sdk/internal/configs" 6 "github.com/hashicorp/terraform-plugin-sdk/internal/dag" 7 "github.com/hashicorp/terraform-plugin-sdk/internal/states" 8 "github.com/hashicorp/terraform-plugin-sdk/internal/tfdiags" 9 ) 10 11 // EvalGraphBuilder implements GraphBuilder and constructs a graph suitable 12 // for evaluating in-memory values (input variables, local values, output 13 // values) in the state without any other side-effects. 14 // 15 // This graph is used only in weird cases, such as the "terraform console" 16 // CLI command, where we need to evaluate expressions against the state 17 // without taking any other actions. 18 // 19 // The generated graph will include nodes for providers, resources, etc 20 // just to allow indirect dependencies to be resolved, but these nodes will 21 // not take any actions themselves since we assume that their parts of the 22 // state, if any, are already complete. 23 // 24 // Although the providers are never configured, they must still be available 25 // in order to obtain schema information used for type checking, etc. 26 type EvalGraphBuilder struct { 27 // Config is the configuration tree. 28 Config *configs.Config 29 30 // State is the current state 31 State *states.State 32 33 // Components is a factory for the plug-in components (providers and 34 // provisioners) available for use. 35 Components contextComponentFactory 36 37 // Schemas is the repository of schemas we will draw from to analyse 38 // the configuration. 39 Schemas *Schemas 40 } 41 42 // See GraphBuilder 43 func (b *EvalGraphBuilder) Build(path addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics) { 44 return (&BasicGraphBuilder{ 45 Steps: b.Steps(), 46 Validate: true, 47 Name: "EvalGraphBuilder", 48 }).Build(path) 49 } 50 51 // See GraphBuilder 52 func (b *EvalGraphBuilder) Steps() []GraphTransformer { 53 concreteProvider := func(a *NodeAbstractProvider) dag.Vertex { 54 return &NodeEvalableProvider{ 55 NodeAbstractProvider: a, 56 } 57 } 58 59 steps := []GraphTransformer{ 60 // Creates all the data resources that aren't in the state. This will also 61 // add any orphans from scaling in as destroy nodes. 62 &ConfigTransformer{ 63 Concrete: nil, // just use the abstract type 64 Config: b.Config, 65 Unique: true, 66 }, 67 68 // Attach the state 69 &AttachStateTransformer{State: b.State}, 70 71 // Attach the configuration to any resources 72 &AttachResourceConfigTransformer{Config: b.Config}, 73 74 // Add root variables 75 &RootVariableTransformer{Config: b.Config}, 76 77 // Add the local values 78 &LocalTransformer{Config: b.Config}, 79 80 // Add the outputs 81 &OutputTransformer{Config: b.Config}, 82 83 // Add module variables 84 &ModuleVariableTransformer{Config: b.Config}, 85 86 TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config), 87 88 // Must attach schemas before ReferenceTransformer so that we can 89 // analyze the configuration to find references. 90 &AttachSchemaTransformer{Schemas: b.Schemas}, 91 92 // Connect so that the references are ready for targeting. We'll 93 // have to connect again later for providers and so on. 94 &ReferenceTransformer{}, 95 96 // Although we don't configure providers, we do still start them up 97 // to get their schemas, and so we must shut them down again here. 98 &CloseProviderTransformer{}, 99 100 // Single root 101 &RootTransformer{}, 102 103 // Remove redundant edges to simplify the graph. 104 &TransitiveReductionTransformer{}, 105 } 106 107 return steps 108 }