77 "context"
88 "fmt"
99 "log"
10- "maps"
1110 "reflect"
12- "slices"
1311 "sort"
1412 "strings"
1513
@@ -28,7 +26,6 @@ import (
2826 "github.com/hashicorp/terraform/internal/configs"
2927 "github.com/hashicorp/terraform/internal/configs/configschema"
3028 "github.com/hashicorp/terraform/internal/depsfile"
31- "github.com/hashicorp/terraform/internal/didyoumean"
3229 "github.com/hashicorp/terraform/internal/getproviders"
3330 "github.com/hashicorp/terraform/internal/getproviders/providerreqs"
3431 "github.com/hashicorp/terraform/internal/providercache"
@@ -155,104 +152,16 @@ func (c *InitCommand) initCloud(ctx context.Context, root *configs.Module, extra
155152 return back , true , diags
156153}
157154
158- func (c * InitCommand ) initBackend (ctx context.Context , root * configs.Module , initArgs * arguments.Init , configLocks * depsfile. Locks , view views.Init ) (be backend.Backend , output bool , diags tfdiags.Diagnostics ) {
155+ func (c * InitCommand ) initBackend (ctx context.Context , root * configs.Module , extraConfig arguments.FlagNameValueSlice , viewType arguments. ViewType , view views.Init ) (be backend.Backend , output bool , diags tfdiags.Diagnostics ) {
159156 ctx , span := tracer .Start (ctx , "initialize backend" )
160157 _ = ctx // prevent staticcheck from complaining to avoid a maintenance hazard of having the wrong ctx in scope here
161158 defer span .End ()
162159
163- if root .StateStore != nil {
164- view .Output (views .InitializingStateStoreMessage )
165- } else {
166- view .Output (views .InitializingBackendMessage )
167- }
168-
169- var opts * BackendOpts
170- switch {
171- case root .StateStore != nil && root .Backend != nil :
172- // We expect validation during config parsing to prevent mutually exclusive backend and state_store blocks,
173- // but checking here just in case.
174- diags = diags .Append (& hcl.Diagnostic {
175- Severity : hcl .DiagError ,
176- Summary : "Conflicting backend and state_store configurations present during init" ,
177- Detail : fmt .Sprintf ("When initializing the backend there was configuration data present for both backend %q and state store %q. This is a bug in Terraform and should be reported." ,
178- root .Backend .Type ,
179- root .StateStore .Type ,
180- ),
181- Subject : & root .Backend .TypeRange ,
182- })
183- return nil , true , diags
184- case root .StateStore != nil :
185- // state_store config present
186- factory , fDiags := c .Meta .GetStateStoreProviderFactory (root .StateStore , configLocks )
187- diags = diags .Append (fDiags )
188- if fDiags .HasErrors () {
189- return nil , true , diags
190- }
191-
192- // If overrides supplied by -backend-config CLI flag, process them
193- var configOverride hcl.Body
194- if ! initArgs .BackendConfig .Empty () {
195- // We need to launch an instance of the provider to get the config of the state store for processing any overrides.
196- provider , err := factory ()
197- defer provider .Close () // Stop the child process once we're done with it here.
198- if err != nil {
199- diags = diags .Append (fmt .Errorf ("error when obtaining provider instance during state store initialization: %w" , err ))
200- return nil , true , diags
201- }
202-
203- resp := provider .GetProviderSchema ()
204-
205- if len (resp .StateStores ) == 0 {
206- diags = diags .Append (& hcl.Diagnostic {
207- Severity : hcl .DiagError ,
208- Summary : "Provider does not support pluggable state storage" ,
209- Detail : fmt .Sprintf ("There are no state stores implemented by provider %s (%q)" ,
210- root .StateStore .Provider .Name ,
211- root .StateStore .ProviderAddr ),
212- Subject : & root .StateStore .DeclRange ,
213- })
214- return nil , true , diags
215- }
216-
217- stateStoreSchema , exists := resp .StateStores [root .StateStore .Type ]
218- if ! exists {
219- suggestions := slices .Sorted (maps .Keys (resp .StateStores ))
220- suggestion := didyoumean .NameSuggestion (root .StateStore .Type , suggestions )
221- if suggestion != "" {
222- suggestion = fmt .Sprintf (" Did you mean %q?" , suggestion )
223- }
224- diags = diags .Append (& hcl.Diagnostic {
225- Severity : hcl .DiagError ,
226- Summary : "State store not implemented by the provider" ,
227- Detail : fmt .Sprintf ("State store %q is not implemented by provider %s (%q)%s" ,
228- root .StateStore .Type , root .StateStore .Provider .Name ,
229- root .StateStore .ProviderAddr , suggestion ),
230- Subject : & root .StateStore .DeclRange ,
231- })
232- return nil , true , diags
233- }
160+ view .Output (views .InitializingBackendMessage )
234161
235- // Handle any overrides supplied via -backend-config CLI flags
236- var overrideDiags tfdiags.Diagnostics
237- configOverride , overrideDiags = c .backendConfigOverrideBody (initArgs .BackendConfig , stateStoreSchema .Body )
238- diags = diags .Append (overrideDiags )
239- if overrideDiags .HasErrors () {
240- return nil , true , diags
241- }
242- }
243-
244- opts = & BackendOpts {
245- StateStoreConfig : root .StateStore ,
246- Locks : configLocks ,
247- ProviderFactory : factory ,
248- CreateDefaultWorkspace : initArgs .CreateDefaultWorkspace ,
249- ConfigOverride : configOverride ,
250- Init : true ,
251- ViewType : initArgs .ViewType ,
252- }
253-
254- case root .Backend != nil :
255- // backend config present
162+ var backendConfig * configs.Backend
163+ var backendConfigOverride hcl.Body
164+ if root .Backend != nil {
256165 backendType := root .Backend .Type
257166 if backendType == "cloud" {
258167 diags = diags .Append (& hcl.Diagnostic {
@@ -282,33 +191,19 @@ func (c *InitCommand) initBackend(ctx context.Context, root *configs.Module, ini
282191
283192 b := bf ()
284193 backendSchema := b .ConfigSchema ()
285- backendConfig := root .Backend
286-
287- // If overrides supplied by -backend-config CLI flag, process them
288- var configOverride hcl.Body
289- if ! initArgs .BackendConfig .Empty () {
290- var overrideDiags tfdiags.Diagnostics
291- configOverride , overrideDiags = c .backendConfigOverrideBody (initArgs .BackendConfig , backendSchema )
292- diags = diags .Append (overrideDiags )
293- if overrideDiags .HasErrors () {
294- return nil , true , diags
295- }
296- }
194+ backendConfig = root .Backend
297195
298- opts = & BackendOpts {
299- BackendConfig : backendConfig ,
300- ConfigOverride : configOverride ,
301- Init : true ,
302- ViewType : initArgs . ViewType ,
196+ var overrideDiags tfdiags. Diagnostics
197+ backendConfigOverride , overrideDiags = c . backendConfigOverrideBody ( extraConfig , backendSchema )
198+ diags = diags . Append ( overrideDiags )
199+ if overrideDiags . HasErrors () {
200+ return nil , true , diags
303201 }
304-
305- default :
306- // No config; defaults to local state storage
307-
202+ } else {
308203 // If the user supplied a -backend-config on the CLI but no backend
309204 // block was found in the configuration, it's likely - but not
310205 // necessarily - a mistake. Return a warning.
311- if ! initArgs . BackendConfig .Empty () {
206+ if ! extraConfig .Empty () {
312207 diags = diags .Append (tfdiags .Sourceless (
313208 tfdiags .Warning ,
314209 "Missing backend configuration" ,
@@ -326,13 +221,14 @@ However, if you intended to override a defined backend, please verify that
326221the backend configuration is present and valid.
327222` ,
328223 ))
329-
330224 }
225+ }
331226
332- opts = & BackendOpts {
333- Init : true ,
334- ViewType : initArgs .ViewType ,
335- }
227+ opts := & BackendOpts {
228+ BackendConfig : backendConfig ,
229+ ConfigOverride : backendConfigOverride ,
230+ Init : true ,
231+ ViewType : viewType ,
336232 }
337233
338234 back , backDiags := c .Backend (opts )
0 commit comments