]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/terraform/graph_builder_apply.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / terraform / graph_builder_apply.go
1 package terraform
2
3 import (
4 "github.com/hashicorp/terraform/addrs"
5 "github.com/hashicorp/terraform/configs"
6 "github.com/hashicorp/terraform/dag"
7 "github.com/hashicorp/terraform/plans"
8 "github.com/hashicorp/terraform/states"
9 "github.com/hashicorp/terraform/tfdiags"
10 )
11
12 // ApplyGraphBuilder implements GraphBuilder and is responsible for building
13 // a graph for applying a Terraform diff.
14 //
15 // Because the graph is built from the diff (vs. the config or state),
16 // this helps ensure that the apply-time graph doesn't modify any resources
17 // that aren't explicitly in the diff. There are other scenarios where the
18 // diff can be deviated, so this is just one layer of protection.
19 type ApplyGraphBuilder struct {
20 // Config is the configuration tree that the diff was built from.
21 Config *configs.Config
22
23 // Changes describes the changes that we need apply.
24 Changes *plans.Changes
25
26 // State is the current state
27 State *states.State
28
29 // Components is a factory for the plug-in components (providers and
30 // provisioners) available for use.
31 Components contextComponentFactory
32
33 // Schemas is the repository of schemas we will draw from to analyse
34 // the configuration.
35 Schemas *Schemas
36
37 // Targets are resources to target. This is only required to make sure
38 // unnecessary outputs aren't included in the apply graph. The plan
39 // builder successfully handles targeting resources. In the future,
40 // outputs should go into the diff so that this is unnecessary.
41 Targets []addrs.Targetable
42
43 // DisableReduce, if true, will not reduce the graph. Great for testing.
44 DisableReduce bool
45
46 // Destroy, if true, represents a pure destroy operation
47 Destroy bool
48
49 // Validate will do structural validation of the graph.
50 Validate bool
51 }
52
53 // See GraphBuilder
54 func (b *ApplyGraphBuilder) Build(path addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics) {
55 return (&BasicGraphBuilder{
56 Steps: b.Steps(),
57 Validate: b.Validate,
58 Name: "ApplyGraphBuilder",
59 }).Build(path)
60 }
61
62 // See GraphBuilder
63 func (b *ApplyGraphBuilder) Steps() []GraphTransformer {
64 // Custom factory for creating providers.
65 concreteProvider := func(a *NodeAbstractProvider) dag.Vertex {
66 return &NodeApplyableProvider{
67 NodeAbstractProvider: a,
68 }
69 }
70
71 concreteResource := func(a *NodeAbstractResource) dag.Vertex {
72 return &NodeApplyableResource{
73 NodeAbstractResource: a,
74 }
75 }
76
77 concreteOrphanResource := func(a *NodeAbstractResource) dag.Vertex {
78 return &NodeDestroyResource{
79 NodeAbstractResource: a,
80 }
81 }
82
83 concreteResourceInstance := func(a *NodeAbstractResourceInstance) dag.Vertex {
84 return &NodeApplyableResourceInstance{
85 NodeAbstractResourceInstance: a,
86 }
87 }
88
89 steps := []GraphTransformer{
90 // Creates all the resources represented in the config. During apply,
91 // we use this just to ensure that the whole-resource metadata is
92 // updated to reflect things such as whether the count argument is
93 // set in config, or which provider configuration manages each resource.
94 &ConfigTransformer{
95 Concrete: concreteResource,
96 Config: b.Config,
97 },
98
99 // Creates all the resource instances represented in the diff, along
100 // with dependency edges against the whole-resource nodes added by
101 // ConfigTransformer above.
102 &DiffTransformer{
103 Concrete: concreteResourceInstance,
104 State: b.State,
105 Changes: b.Changes,
106 },
107
108 // Creates extra cleanup nodes for any entire resources that are
109 // no longer present in config, so we can make sure we clean up the
110 // leftover empty resource states after the instances have been
111 // destroyed.
112 // (We don't track this particular type of change in the plan because
113 // it's just cleanup of our own state object, and so doesn't effect
114 // any real remote objects or consumable outputs.)
115 &OrphanResourceTransformer{
116 Concrete: concreteOrphanResource,
117 Config: b.Config,
118 State: b.State,
119 },
120
121 // Create orphan output nodes
122 &OrphanOutputTransformer{Config: b.Config, State: b.State},
123
124 // Attach the configuration to any resources
125 &AttachResourceConfigTransformer{Config: b.Config},
126
127 // Attach the state
128 &AttachStateTransformer{State: b.State},
129
130 // Destruction ordering
131 &DestroyEdgeTransformer{
132 Config: b.Config,
133 State: b.State,
134 Schemas: b.Schemas,
135 },
136 GraphTransformIf(
137 func() bool { return !b.Destroy },
138 &CBDEdgeTransformer{
139 Config: b.Config,
140 State: b.State,
141 Schemas: b.Schemas,
142 },
143 ),
144
145 // Provisioner-related transformations
146 &MissingProvisionerTransformer{Provisioners: b.Components.ResourceProvisioners()},
147 &ProvisionerTransformer{},
148
149 // Add root variables
150 &RootVariableTransformer{Config: b.Config},
151
152 // Add the local values
153 &LocalTransformer{Config: b.Config},
154
155 // Add the outputs
156 &OutputTransformer{Config: b.Config},
157
158 // Add module variables
159 &ModuleVariableTransformer{Config: b.Config},
160
161 // add providers
162 TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config),
163
164 // Remove modules no longer present in the config
165 &RemovedModuleTransformer{Config: b.Config, State: b.State},
166
167 // Must attach schemas before ReferenceTransformer so that we can
168 // analyze the configuration to find references.
169 &AttachSchemaTransformer{Schemas: b.Schemas},
170
171 // Connect references so ordering is correct
172 &ReferenceTransformer{},
173
174 // Handle destroy time transformations for output and local values.
175 // Reverse the edges from outputs and locals, so that
176 // interpolations don't fail during destroy.
177 // Create a destroy node for outputs to remove them from the state.
178 // Prune unreferenced values, which may have interpolations that can't
179 // be resolved.
180 GraphTransformIf(
181 func() bool { return b.Destroy },
182 GraphTransformMulti(
183 &DestroyValueReferenceTransformer{},
184 &DestroyOutputTransformer{},
185 &PruneUnusedValuesTransformer{},
186 ),
187 ),
188
189 // Add the node to fix the state count boundaries
190 &CountBoundaryTransformer{
191 Config: b.Config,
192 },
193
194 // Target
195 &TargetsTransformer{Targets: b.Targets},
196
197 // Close opened plugin connections
198 &CloseProviderTransformer{},
199 &CloseProvisionerTransformer{},
200
201 // Single root
202 &RootTransformer{},
203 }
204
205 if !b.DisableReduce {
206 // Perform the transitive reduction to make our graph a bit
207 // more sane if possible (it usually is possible).
208 steps = append(steps, &TransitiveReductionTransformer{})
209 }
210
211 return steps
212 }