github.com/rhenning/terraform@v0.8.0-beta2/terraform/graph_builder_plan.go (about) 1 package terraform 2 3 import ( 4 "github.com/hashicorp/terraform/config/module" 5 "github.com/hashicorp/terraform/dag" 6 ) 7 8 // PlanGraphBuilder implements GraphBuilder and is responsible for building 9 // a graph for planning (creating a Terraform Diff). 10 // 11 // The primary difference between this graph and others: 12 // 13 // * Based on the config since it represents the target state 14 // 15 // * Ignores lifecycle options since no lifecycle events occur here. This 16 // simplifies the graph significantly since complex transforms such as 17 // create-before-destroy can be completely ignored. 18 // 19 type PlanGraphBuilder struct { 20 // Module is the root module for the graph to build. 21 Module *module.Tree 22 23 // State is the current state 24 State *State 25 26 // Providers is the list of providers supported. 27 Providers []string 28 29 // Targets are resources to target 30 Targets []string 31 32 // DisableReduce, if true, will not reduce the graph. Great for testing. 33 DisableReduce bool 34 } 35 36 // See GraphBuilder 37 func (b *PlanGraphBuilder) Build(path []string) (*Graph, error) { 38 return (&BasicGraphBuilder{ 39 Steps: b.Steps(), 40 Validate: true, 41 Name: "plan", 42 }).Build(path) 43 } 44 45 // See GraphBuilder 46 func (b *PlanGraphBuilder) Steps() []GraphTransformer { 47 // Custom factory for creating providers. 48 providerFactory := func(name string, path []string) GraphNodeProvider { 49 return &NodeApplyableProvider{ 50 NameValue: name, 51 PathValue: path, 52 } 53 } 54 55 concreteResource := func(a *NodeAbstractResource) dag.Vertex { 56 return &NodePlannableResource{ 57 NodeAbstractResource: a, 58 } 59 } 60 61 concreteResourceOrphan := func(a *NodeAbstractResource) dag.Vertex { 62 return &NodePlannableResourceOrphan{ 63 NodeAbstractResource: a, 64 } 65 } 66 67 steps := []GraphTransformer{ 68 // Creates all the resources represented in the config 69 &ConfigTransformer{ 70 Concrete: concreteResource, 71 Module: b.Module, 72 }, 73 74 // Add the outputs 75 &OutputTransformer{Module: b.Module}, 76 77 // Add orphan resources 78 &OrphanResourceTransformer{ 79 Concrete: concreteResourceOrphan, 80 State: b.State, 81 Module: b.Module, 82 }, 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 // Connect so that the references are ready for targeting. We'll 91 // have to connect again later for providers and so on. 92 &ReferenceTransformer{}, 93 94 // Target 95 &TargetsTransformer{Targets: b.Targets}, 96 97 // Create all the providers 98 &MissingProviderTransformer{Providers: b.Providers, Factory: providerFactory}, 99 &ProviderTransformer{}, 100 &DisableProviderTransformer{}, 101 &ParentProviderTransformer{}, 102 &AttachProviderConfigTransformer{Module: b.Module}, 103 104 // Add root variables 105 &RootVariableTransformer{Module: b.Module}, 106 107 // Add module variables 108 &ModuleVariableTransformer{Module: b.Module}, 109 110 // Connect references again to connect the providers, module variables, 111 // etc. This is idempotent. 112 &ReferenceTransformer{}, 113 114 // Single root 115 &RootTransformer{}, 116 } 117 118 if !b.DisableReduce { 119 // Perform the transitive reduction to make our graph a bit 120 // more sane if possible (it usually is possible). 121 steps = append(steps, &TransitiveReductionTransformer{}) 122 } 123 124 return steps 125 }