]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blame - 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
CommitLineData
bae9f6d2
JC
1package terraform
2
3import (
107c1cdb
ND
4 "github.com/hashicorp/terraform/addrs"
5 "github.com/hashicorp/terraform/configs"
bae9f6d2 6 "github.com/hashicorp/terraform/dag"
107c1cdb
ND
7 "github.com/hashicorp/terraform/plans"
8 "github.com/hashicorp/terraform/states"
9 "github.com/hashicorp/terraform/tfdiags"
bae9f6d2
JC
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.
19type ApplyGraphBuilder struct {
107c1cdb
ND
20 // Config is the configuration tree that the diff was built from.
21 Config *configs.Config
bae9f6d2 22
107c1cdb
ND
23 // Changes describes the changes that we need apply.
24 Changes *plans.Changes
bae9f6d2
JC
25
26 // State is the current state
107c1cdb 27 State *states.State
bae9f6d2 28
107c1cdb
ND
29 // Components is a factory for the plug-in components (providers and
30 // provisioners) available for use.
31 Components contextComponentFactory
bae9f6d2 32
107c1cdb
ND
33 // Schemas is the repository of schemas we will draw from to analyse
34 // the configuration.
35 Schemas *Schemas
bae9f6d2
JC
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.
107c1cdb 41 Targets []addrs.Targetable
bae9f6d2
JC
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
107c1cdb 54func (b *ApplyGraphBuilder) Build(path addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics) {
bae9f6d2
JC
55 return (&BasicGraphBuilder{
56 Steps: b.Steps(),
57 Validate: b.Validate,
58 Name: "ApplyGraphBuilder",
59 }).Build(path)
60}
61
62// See GraphBuilder
63func (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
107c1cdb
ND
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
bae9f6d2 89 steps := []GraphTransformer{
107c1cdb
ND
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{
bae9f6d2 95 Concrete: concreteResource,
107c1cdb
ND
96 Config: b.Config,
97 },
bae9f6d2 98
107c1cdb
ND
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,
bae9f6d2
JC
119 },
120
121 // Create orphan output nodes
107c1cdb 122 &OrphanOutputTransformer{Config: b.Config, State: b.State},
bae9f6d2
JC
123
124 // Attach the configuration to any resources
107c1cdb 125 &AttachResourceConfigTransformer{Config: b.Config},
bae9f6d2
JC
126
127 // Attach the state
128 &AttachStateTransformer{State: b.State},
129
bae9f6d2 130 // Destruction ordering
107c1cdb
ND
131 &DestroyEdgeTransformer{
132 Config: b.Config,
133 State: b.State,
134 Schemas: b.Schemas,
135 },
bae9f6d2
JC
136 GraphTransformIf(
137 func() bool { return !b.Destroy },
107c1cdb
ND
138 &CBDEdgeTransformer{
139 Config: b.Config,
140 State: b.State,
141 Schemas: b.Schemas,
142 },
bae9f6d2
JC
143 ),
144
145 // Provisioner-related transformations
107c1cdb 146 &MissingProvisionerTransformer{Provisioners: b.Components.ResourceProvisioners()},
bae9f6d2
JC
147 &ProvisionerTransformer{},
148
149 // Add root variables
107c1cdb 150 &RootVariableTransformer{Config: b.Config},
bae9f6d2 151
15c0b25d 152 // Add the local values
107c1cdb 153 &LocalTransformer{Config: b.Config},
15c0b25d 154
bae9f6d2 155 // Add the outputs
107c1cdb 156 &OutputTransformer{Config: b.Config},
bae9f6d2
JC
157
158 // Add module variables
107c1cdb
ND
159 &ModuleVariableTransformer{Config: b.Config},
160
161 // add providers
162 TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config),
bae9f6d2 163
15c0b25d 164 // Remove modules no longer present in the config
107c1cdb
ND
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},
15c0b25d 170
bae9f6d2
JC
171 // Connect references so ordering is correct
172 &ReferenceTransformer{},
173
15c0b25d
AP
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
bae9f6d2 189 // Add the node to fix the state count boundaries
107c1cdb
ND
190 &CountBoundaryTransformer{
191 Config: b.Config,
192 },
bae9f6d2
JC
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}