github.com/paybyphone/terraform@v0.9.5-0.20170613192930-9706042ddd51/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 // Create all the providers 91 &MissingProviderTransformer{Providers: b.Providers, Concrete: concreteProvider}, 92 &ProviderTransformer{}, 93 &DisableProviderTransformer{}, 94 &ParentProviderTransformer{}, 95 &AttachProviderConfigTransformer{Module: b.Module}, 96 97 // Destruction ordering 98 &DestroyEdgeTransformer{Module: b.Module, State: b.State}, 99 GraphTransformIf( 100 func() bool { return !b.Destroy }, 101 &CBDEdgeTransformer{Module: b.Module, State: b.State}, 102 ), 103 104 // Provisioner-related transformations 105 &MissingProvisionerTransformer{Provisioners: b.Provisioners}, 106 &ProvisionerTransformer{}, 107 108 // Add root variables 109 &RootVariableTransformer{Module: b.Module}, 110 111 // Add the outputs 112 &OutputTransformer{Module: b.Module}, 113 114 // Add module variables 115 &ModuleVariableTransformer{Module: b.Module}, 116 117 // Connect references so ordering is correct 118 &ReferenceTransformer{}, 119 120 // Add the node to fix the state count boundaries 121 &CountBoundaryTransformer{}, 122 123 // Target 124 &TargetsTransformer{Targets: b.Targets}, 125 126 // Close opened plugin connections 127 &CloseProviderTransformer{}, 128 &CloseProvisionerTransformer{}, 129 130 // Single root 131 &RootTransformer{}, 132 } 133 134 if !b.DisableReduce { 135 // Perform the transitive reduction to make our graph a bit 136 // more sane if possible (it usually is possible). 137 steps = append(steps, &TransitiveReductionTransformer{}) 138 } 139 140 return steps 141 }