github.com/wikibal01/hashicorp-terraform@v0.11.12-beta1/terraform/graph_builder_apply.go (about) 1 package terraform 2 3 import ( 4 "github.com/hashicorp/terraform/config/module" 5 "github.com/hashicorp/terraform/dag" 6 ) 7 8 // ApplyGraphBuilder implements GraphBuilder and is responsible for building 9 // a graph for applying a Terraform diff. 10 // 11 // Because the graph is built from the diff (vs. the config or state), 12 // this helps ensure that the apply-time graph doesn't modify any resources 13 // that aren't explicitly in the diff. There are other scenarios where the 14 // diff can be deviated, so this is just one layer of protection. 15 type ApplyGraphBuilder struct { 16 // Module is the root module for the graph to build. 17 Module *module.Tree 18 19 // Diff is the diff to apply. 20 Diff *Diff 21 22 // State is the current state 23 State *State 24 25 // Providers is the list of providers supported. 26 Providers []string 27 28 // Provisioners is the list of provisioners supported. 29 Provisioners []string 30 31 // Targets are resources to target. This is only required to make sure 32 // unnecessary outputs aren't included in the apply graph. The plan 33 // builder successfully handles targeting resources. In the future, 34 // outputs should go into the diff so that this is unnecessary. 35 Targets []string 36 37 // DisableReduce, if true, will not reduce the graph. Great for testing. 38 DisableReduce bool 39 40 // Destroy, if true, represents a pure destroy operation 41 Destroy bool 42 43 // Validate will do structural validation of the graph. 44 Validate bool 45 } 46 47 // See GraphBuilder 48 func (b *ApplyGraphBuilder) Build(path []string) (*Graph, error) { 49 return (&BasicGraphBuilder{ 50 Steps: b.Steps(), 51 Validate: b.Validate, 52 Name: "ApplyGraphBuilder", 53 }).Build(path) 54 } 55 56 // See GraphBuilder 57 func (b *ApplyGraphBuilder) Steps() []GraphTransformer { 58 // Custom factory for creating providers. 59 concreteProvider := func(a *NodeAbstractProvider) dag.Vertex { 60 return &NodeApplyableProvider{ 61 NodeAbstractProvider: a, 62 } 63 } 64 65 concreteResource := func(a *NodeAbstractResource) dag.Vertex { 66 return &NodeApplyableResource{ 67 NodeAbstractResource: a, 68 } 69 } 70 71 steps := []GraphTransformer{ 72 // Creates all the nodes represented in the diff. 73 &DiffTransformer{ 74 Concrete: concreteResource, 75 76 Diff: b.Diff, 77 Module: b.Module, 78 State: b.State, 79 }, 80 81 // Create orphan output nodes 82 &OrphanOutputTransformer{Module: b.Module, State: b.State}, 83 84 // Attach the configuration to any resources 85 &AttachResourceConfigTransformer{Module: b.Module}, 86 87 // Attach the state 88 &AttachStateTransformer{State: b.State}, 89 90 // add providers 91 TransformProviders(b.Providers, concreteProvider, b.Module), 92 93 // Destruction ordering 94 &DestroyEdgeTransformer{Module: b.Module, State: b.State}, 95 GraphTransformIf( 96 func() bool { return !b.Destroy }, 97 &CBDEdgeTransformer{Module: b.Module, State: b.State}, 98 ), 99 100 // Provisioner-related transformations 101 &MissingProvisionerTransformer{Provisioners: b.Provisioners}, 102 &ProvisionerTransformer{}, 103 104 // Add root variables 105 &RootVariableTransformer{Module: b.Module}, 106 107 // Add the local values 108 &LocalTransformer{Module: b.Module}, 109 110 // Add the outputs 111 &OutputTransformer{Module: b.Module}, 112 113 // Add module variables 114 &ModuleVariableTransformer{Module: b.Module}, 115 116 // Remove modules no longer present in the config 117 &RemovedModuleTransformer{Module: b.Module, State: b.State}, 118 119 // Connect references so ordering is correct 120 &ReferenceTransformer{}, 121 122 // Handle destroy time transformations for output and local values. 123 // Reverse the edges from outputs and locals, so that 124 // interpolations don't fail during destroy. 125 // Create a destroy node for outputs to remove them from the state. 126 // Prune unreferenced values, which may have interpolations that can't 127 // be resolved. 128 GraphTransformIf( 129 func() bool { return b.Destroy }, 130 GraphTransformMulti( 131 &DestroyValueReferenceTransformer{}, 132 &DestroyOutputTransformer{}, 133 &PruneUnusedValuesTransformer{}, 134 ), 135 ), 136 137 // Add the node to fix the state count boundaries 138 &CountBoundaryTransformer{}, 139 140 // Target 141 &TargetsTransformer{Targets: b.Targets}, 142 143 // Close opened plugin connections 144 &CloseProviderTransformer{}, 145 &CloseProvisionerTransformer{}, 146 147 // Single root 148 &RootTransformer{}, 149 } 150 151 if !b.DisableReduce { 152 // Perform the transitive reduction to make our graph a bit 153 // more sane if possible (it usually is possible). 154 steps = append(steps, &TransitiveReductionTransformer{}) 155 } 156 157 return steps 158 }