github.com/trawler/terraform@v0.10.8-0.20171106022149-4b1c7a1d9b48/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 // Connect references so ordering is correct 117 &ReferenceTransformer{}, 118 119 // Reverse the edges to outputs and locals, so that 120 // interpolations don't fail during destroy. 121 GraphTransformIf( 122 func() bool { return b.Destroy }, 123 &DestroyValueReferenceTransformer{}, 124 ), 125 126 // Add the node to fix the state count boundaries 127 &CountBoundaryTransformer{}, 128 129 // Target 130 &TargetsTransformer{Targets: b.Targets}, 131 132 // Close opened plugin connections 133 &CloseProviderTransformer{}, 134 &CloseProvisionerTransformer{}, 135 136 // Single root 137 &RootTransformer{}, 138 } 139 140 if !b.DisableReduce { 141 // Perform the transitive reduction to make our graph a bit 142 // more sane if possible (it usually is possible). 143 steps = append(steps, &TransitiveReductionTransformer{}) 144 } 145 146 return steps 147 }