github.com/kanishk98/terraform@v1.3.0-dev.0.20220917174235-661ca8088a6a/internal/terraform/graph_builder_eval.go (about) 1 package terraform 2 3 import ( 4 "github.com/hashicorp/terraform/internal/addrs" 5 "github.com/hashicorp/terraform/internal/configs" 6 "github.com/hashicorp/terraform/internal/dag" 7 "github.com/hashicorp/terraform/internal/states" 8 "github.com/hashicorp/terraform/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 // RootVariableValues are the raw input values for root input variables 34 // given by the caller, which we'll resolve into final values as part 35 // of the plan walk. 36 RootVariableValues InputValues 37 38 // Plugins is a library of plug-in components (providers and 39 // provisioners) available for use. 40 Plugins *contextPlugins 41 } 42 43 // See GraphBuilder 44 func (b *EvalGraphBuilder) Build(path addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics) { 45 return (&BasicGraphBuilder{ 46 Steps: b.Steps(), 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 Config: b.Config, 64 }, 65 66 // Add dynamic values 67 &RootVariableTransformer{Config: b.Config, RawValues: b.RootVariableValues}, 68 &ModuleVariableTransformer{Config: b.Config}, 69 &LocalTransformer{Config: b.Config}, 70 &OutputTransformer{Config: b.Config}, 71 72 // Attach the configuration to any resources 73 &AttachResourceConfigTransformer{Config: b.Config}, 74 75 // Attach the state 76 &AttachStateTransformer{State: b.State}, 77 78 transformProviders(concreteProvider, b.Config), 79 80 // Must attach schemas before ReferenceTransformer so that we can 81 // analyze the configuration to find references. 82 &AttachSchemaTransformer{Plugins: b.Plugins, Config: b.Config}, 83 84 // Create expansion nodes for all of the module calls. This must 85 // come after all other transformers that create nodes representing 86 // objects that can belong to modules. 87 &ModuleExpansionTransformer{Config: b.Config}, 88 89 // Connect so that the references are ready for targeting. We'll 90 // have to connect again later for providers and so on. 91 &ReferenceTransformer{}, 92 93 // Although we don't configure providers, we do still start them up 94 // to get their schemas, and so we must shut them down again here. 95 &CloseProviderTransformer{}, 96 97 // Close root module 98 &CloseRootModuleTransformer{}, 99 100 // Remove redundant edges to simplify the graph. 101 &TransitiveReductionTransformer{}, 102 } 103 104 return steps 105 }