diff --git a/internal/command/meta_backend.go b/internal/command/meta_backend.go index 4e0b09555..825de47e6 100644 --- a/internal/command/meta_backend.go +++ b/internal/command/meta_backend.go @@ -97,14 +97,6 @@ func (m *Meta) Backend(opts *BackendOpts) (backend.Enhanced, tfdiags.Diagnostics b, backendDiags = m.backendFromConfig(opts) diags = diags.Append(backendDiags) - if opts.Init && b != nil && !diags.HasErrors() { - // Its possible that the currently selected workspace doesn't exist, so - // we call selectWorkspace to ensure an existing workspace is selected. - if err := m.selectWorkspace(b); err != nil { - diags = diags.Append(err) - } - } - if diags.HasErrors() { return nil, diags } @@ -232,8 +224,11 @@ func (m *Meta) selectWorkspace(b backend.Backend) error { Query: "\n[reset][bold][yellow]No workspaces found.[reset]", Description: fmt.Sprintf(inputCloudInitCreateWorkspace, strings.Join(c.WorkspaceMapping.Tags, ", ")), }) + if err != nil { + return fmt.Errorf("Couldn't create initial workspace: %w", err) + } name = strings.TrimSpace(name) - if err != nil || name == "" { + if name == "" { return fmt.Errorf("Couldn't create initial workspace: no name provided") } log.Printf("[TRACE] Meta.selectWorkspace: selecting the new TFC workspace requested by the user (%s)", name) @@ -610,7 +605,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di return m.backend_c_r_S(c, cHash, sMgr, true) - // Configuring a backend for the first time. + // Configuring a backend for the first time or -reconfigure flag was used case c != nil && s.Backend.Empty(): log.Printf("[TRACE] Meta.Backend: moving from default local state only to %q backend", c.Type) if !opts.Init { @@ -631,9 +626,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di } return nil, diags } - - return m.backend_C_r_s(c, cHash, sMgr) - + return m.backend_C_r_s(c, cHash, sMgr, opts) // Potentially changing a backend configuration case c != nil && !s.Backend.Empty(): // We are not going to migrate if... @@ -643,7 +636,15 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di // AND we're not providing any overrides. An override can mean a change overriding an unchanged backend block (indicated by the hash value). if (uint64(cHash) == s.Backend.Hash) && (!opts.Init || opts.ConfigOverride == nil) { log.Printf("[TRACE] Meta.Backend: using already-initialized, unchanged %q backend configuration", c.Type) - return m.savedBackend(sMgr) + savedBackend, diags := m.savedBackend(sMgr) + // Verify that selected workspace exist. Otherwise prompt user to create one + if opts.Init && savedBackend != nil { + if err := m.selectWorkspace(savedBackend); err != nil { + diags = diags.Append(err) + return nil, diags + } + } + return savedBackend, diags } // If our configuration (the result of both the literal configuration and given @@ -665,6 +666,13 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di if moreDiags.HasErrors() { return nil, diags } + // Verify that selected workspace exist. Otherwise prompt user to create one + if opts.Init && savedBackend != nil { + if err := m.selectWorkspace(savedBackend); err != nil { + diags = diags.Append(err) + return nil, diags + } + } return savedBackend, diags } @@ -685,7 +693,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di } log.Printf("[WARN] backend config has changed since last init") - return m.backend_C_r_S_changed(c, cHash, sMgr, true) + return m.backend_C_r_S_changed(c, cHash, sMgr, true, opts) default: diags = diags.Append(fmt.Errorf( @@ -897,7 +905,7 @@ func (m *Meta) backend_c_r_S(c *configs.Backend, cHash int, sMgr *clistate.Local } // Configuring a backend for the first time. -func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *clistate.LocalState) (backend.Backend, tfdiags.Diagnostics) { +func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *clistate.LocalState, opts *BackendOpts) (backend.Backend, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics // Grab a purely local backend to get the local state if it exists @@ -1017,6 +1025,14 @@ func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *clistate.Local Hash: uint64(cHash), } + // Verify that selected workspace exist. Otherwise prompt user to create one + if opts.Init && b != nil { + if err := m.selectWorkspace(b); err != nil { + diags = diags.Append(err) + return nil, diags + } + } + if err := sMgr.WriteState(s); err != nil { diags = diags.Append(fmt.Errorf(errBackendWriteSaved, err)) return nil, diags @@ -1037,7 +1053,7 @@ func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *clistate.Local } // Changing a previously saved backend. -func (m *Meta) backend_C_r_S_changed(c *configs.Backend, cHash int, sMgr *clistate.LocalState, output bool) (backend.Backend, tfdiags.Diagnostics) { +func (m *Meta) backend_C_r_S_changed(c *configs.Backend, cHash int, sMgr *clistate.LocalState, output bool, opts *BackendOpts) (backend.Backend, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics // Get the old state @@ -1133,6 +1149,14 @@ func (m *Meta) backend_C_r_S_changed(c *configs.Backend, cHash int, sMgr *clista Hash: uint64(cHash), } + // Verify that selected workspace exist. Otherwise prompt user to create one + if opts.Init && b != nil { + if err := m.selectWorkspace(b); err != nil { + diags = diags.Append(err) + return b, diags + } + } + if err := sMgr.WriteState(s); err != nil { diags = diags.Append(fmt.Errorf(errBackendWriteSaved, err)) return nil, diags