github.com/hashicorp/terraform-plugin-sdk@v1.17.2/terraform/graph_builder_refresh.go (about) 1 package terraform 2 3 import ( 4 "log" 5 6 "github.com/hashicorp/terraform-plugin-sdk/internal/states" 7 "github.com/hashicorp/terraform-plugin-sdk/internal/tfdiags" 8 9 "github.com/hashicorp/terraform-plugin-sdk/internal/addrs" 10 "github.com/hashicorp/terraform-plugin-sdk/internal/configs" 11 "github.com/hashicorp/terraform-plugin-sdk/internal/dag" 12 ) 13 14 // RefreshGraphBuilder implements GraphBuilder and is responsible for building 15 // a graph for refreshing (updating the Terraform state). 16 // 17 // The primary difference between this graph and others: 18 // 19 // * Based on the state since it represents the only resources that 20 // need to be refreshed. 21 // 22 // * Ignores lifecycle options since no lifecycle events occur here. This 23 // simplifies the graph significantly since complex transforms such as 24 // create-before-destroy can be completely ignored. 25 // 26 type RefreshGraphBuilder struct { 27 // Config is the configuration tree. 28 Config *configs.Config 29 30 // State is the prior state 31 State *states.State 32 33 // Components is a factory for the plug-in components (providers and 34 // provisioners) available for use. 35 Components contextComponentFactory 36 37 // Schemas is the repository of schemas we will draw from to analyse 38 // the configuration. 39 Schemas *Schemas 40 41 // Targets are resources to target 42 Targets []addrs.Targetable 43 44 // DisableReduce, if true, will not reduce the graph. Great for testing. 45 DisableReduce bool 46 47 // Validate will do structural validation of the graph. 48 Validate bool 49 } 50 51 // See GraphBuilder 52 func (b *RefreshGraphBuilder) Build(path addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics) { 53 return (&BasicGraphBuilder{ 54 Steps: b.Steps(), 55 Validate: b.Validate, 56 Name: "RefreshGraphBuilder", 57 }).Build(path) 58 } 59 60 // See GraphBuilder 61 func (b *RefreshGraphBuilder) Steps() []GraphTransformer { 62 // Custom factory for creating providers. 63 concreteProvider := func(a *NodeAbstractProvider) dag.Vertex { 64 return &NodeApplyableProvider{ 65 NodeAbstractProvider: a, 66 } 67 } 68 69 concreteManagedResource := func(a *NodeAbstractResource) dag.Vertex { 70 return &NodeRefreshableManagedResource{ 71 NodeAbstractResource: a, 72 } 73 } 74 75 concreteManagedResourceInstance := func(a *NodeAbstractResourceInstance) dag.Vertex { 76 return &NodeRefreshableManagedResourceInstance{ 77 NodeAbstractResourceInstance: a, 78 } 79 } 80 81 concreteResourceInstanceDeposed := func(a *NodeAbstractResourceInstance, key states.DeposedKey) dag.Vertex { 82 // The "Plan" node type also handles refreshing behavior. 83 return &NodePlanDeposedResourceInstanceObject{ 84 NodeAbstractResourceInstance: a, 85 DeposedKey: key, 86 } 87 } 88 89 concreteDataResource := func(a *NodeAbstractResource) dag.Vertex { 90 return &NodeRefreshableDataResource{ 91 NodeAbstractResource: a, 92 } 93 } 94 95 steps := []GraphTransformer{ 96 // Creates all the managed resources that aren't in the state, but only if 97 // we have a state already. No resources in state means there's not 98 // anything to refresh. 99 func() GraphTransformer { 100 if b.State.HasResources() { 101 return &ConfigTransformer{ 102 Concrete: concreteManagedResource, 103 Config: b.Config, 104 Unique: true, 105 ModeFilter: true, 106 Mode: addrs.ManagedResourceMode, 107 } 108 } 109 log.Println("[TRACE] No managed resources in state during refresh; skipping managed resource transformer") 110 return nil 111 }(), 112 113 // Creates all the data resources that aren't in the state. This will also 114 // add any orphans from scaling in as destroy nodes. 115 &ConfigTransformer{ 116 Concrete: concreteDataResource, 117 Config: b.Config, 118 Unique: true, 119 ModeFilter: true, 120 Mode: addrs.DataResourceMode, 121 }, 122 123 // Add any fully-orphaned resources from config (ones that have been 124 // removed completely, not ones that are just orphaned due to a scaled-in 125 // count. 126 &OrphanResourceInstanceTransformer{ 127 Concrete: concreteManagedResourceInstance, 128 State: b.State, 129 Config: b.Config, 130 }, 131 132 // We also need nodes for any deposed instance objects present in the 133 // state, so we can check if they still exist. (This intentionally 134 // skips creating nodes for _current_ objects, since ConfigTransformer 135 // created nodes that will do that during DynamicExpand.) 136 &StateTransformer{ 137 ConcreteDeposed: concreteResourceInstanceDeposed, 138 State: b.State, 139 }, 140 141 // Attach the state 142 &AttachStateTransformer{State: b.State}, 143 144 // Attach the configuration to any resources 145 &AttachResourceConfigTransformer{Config: b.Config}, 146 147 // Add root variables 148 &RootVariableTransformer{Config: b.Config}, 149 150 // Add the local values 151 &LocalTransformer{Config: b.Config}, 152 153 // Add the outputs 154 &OutputTransformer{Config: b.Config}, 155 156 // Add module variables 157 &ModuleVariableTransformer{Config: b.Config}, 158 159 TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config), 160 161 // Must attach schemas before ReferenceTransformer so that we can 162 // analyze the configuration to find references. 163 &AttachSchemaTransformer{Schemas: b.Schemas}, 164 165 // Connect so that the references are ready for targeting. We'll 166 // have to connect again later for providers and so on. 167 &ReferenceTransformer{}, 168 169 // Target 170 &TargetsTransformer{ 171 Targets: b.Targets, 172 173 // Resource nodes from config have not yet been expanded for 174 // "count", so we must apply targeting without indices. Exact 175 // targeting will be dealt with later when these resources 176 // DynamicExpand. 177 IgnoreIndices: true, 178 }, 179 180 // Close opened plugin connections 181 &CloseProviderTransformer{}, 182 183 // Single root 184 &RootTransformer{}, 185 } 186 187 if !b.DisableReduce { 188 // Perform the transitive reduction to make our graph a bit 189 // more sane if possible (it usually is possible). 190 steps = append(steps, &TransitiveReductionTransformer{}) 191 } 192 193 return steps 194 }