Merge pull request #29881 from hashicorp/chrisarcand/streamline-remote-migration
cloud: Add streamlined 'remote' backend state migration path
This commit is contained in:
commit
4f66479506
|
@ -569,6 +569,17 @@ func (b *Remote) workspaces() ([]string, error) {
|
|||
return names, nil
|
||||
}
|
||||
|
||||
// WorkspaceNamePattern provides an appropriate workspace renaming pattern for backend migration
|
||||
// purposes (handled outside of this package), based on previous usage of this backend with the
|
||||
// 'prefix' workspace functionality. As of this writing, see meta_backend.migrate.go
|
||||
func (b *Remote) WorkspaceNamePattern() string {
|
||||
if b.prefix != "" {
|
||||
return b.prefix + "*"
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// DeleteWorkspace implements backend.Enhanced.
|
||||
func (b *Remote) DeleteWorkspace(name string) error {
|
||||
if b.workspace == "" && name == backend.DefaultStateName {
|
||||
|
|
|
@ -1002,7 +1002,7 @@ func (m *Meta) backend_C_r_S_changed(c *configs.Backend, cHash int, sMgr *clista
|
|||
if output {
|
||||
// Notify the user
|
||||
m.Ui.Output(m.Colorize().Color(fmt.Sprintf(
|
||||
"[reset]%s\n\n",
|
||||
"[reset]%s\n",
|
||||
strings.TrimSpace(outputBackendReconfigure))))
|
||||
}
|
||||
|
||||
|
@ -1021,7 +1021,9 @@ func (m *Meta) backend_C_r_S_changed(c *configs.Backend, cHash int, sMgr *clista
|
|||
if c.Type == "cloud" {
|
||||
output = fmt.Sprintf(outputBackendMigrateChangeCloud, s.Backend.Type)
|
||||
}
|
||||
m.Ui.Output(strings.TrimSpace(output))
|
||||
m.Ui.Output(m.Colorize().Color(fmt.Sprintf(
|
||||
"[reset]%s\n",
|
||||
strings.TrimSpace(output))))
|
||||
}
|
||||
|
||||
// Grab the existing backend
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/internal/backend"
|
||||
"github.com/hashicorp/terraform/internal/backend/remote"
|
||||
"github.com/hashicorp/terraform/internal/cloud"
|
||||
"github.com/hashicorp/terraform/internal/command/arguments"
|
||||
"github.com/hashicorp/terraform/internal/command/clistate"
|
||||
|
@ -635,10 +636,33 @@ func (m *Meta) backendMigrateState_S_TFC(opts *backendMigrateOpts, sourceWorkspa
|
|||
defaultNewName[sourceWorkspaces[i]] = newName
|
||||
}
|
||||
}
|
||||
pattern, err := m.promptMultiStateMigrationPattern(opts.SourceType)
|
||||
|
||||
// Fetch the pattern that will be used to rename the workspaces for Terraform Cloud.
|
||||
//
|
||||
// * For the general case, this will be a pattern provided by the user.
|
||||
//
|
||||
// * Specifically for a migration from the "remote" backend using 'prefix', we will
|
||||
// instead 'migrate' the workspaces using a pattern based on the old prefix+name,
|
||||
// not allowing a user to accidentally input the wrong pattern to line up with
|
||||
// what the the remote backend was already using before (which presumably already
|
||||
// meets the naming considerations for Terraform Cloud).
|
||||
// In other words, this is a fast-track migration path from the remote backend, retaining
|
||||
// how things already are in Terraform Cloud with no user intervention needed.
|
||||
pattern := ""
|
||||
if remoteBackend, ok := opts.Source.(*remote.Remote); ok {
|
||||
if err := m.promptRemotePrefixToCloudTagsMigration(opts); err != nil {
|
||||
return err
|
||||
}
|
||||
pattern = remoteBackend.WorkspaceNamePattern()
|
||||
log.Printf("[TRACE] backendMigrateTFC: Remote backend reports workspace name pattern as: %q", pattern)
|
||||
}
|
||||
|
||||
if pattern == "" {
|
||||
pattern, err = m.promptMultiStateMigrationPattern(opts.SourceType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Go through each and migrate
|
||||
for _, name := range sourceWorkspaces {
|
||||
|
@ -712,6 +736,27 @@ func (m *Meta) backendMigrateState_S_TFC(opts *backendMigrateOpts, sourceWorkspa
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Meta) promptRemotePrefixToCloudTagsMigration(opts *backendMigrateOpts) error {
|
||||
migrate := opts.force
|
||||
if !migrate {
|
||||
var err error
|
||||
migrate, err = m.confirm(&terraform.InputOpts{
|
||||
Id: "backend-migrate-remote-multistate-to-cloud",
|
||||
Query: "Do you wish to proceed?",
|
||||
Description: strings.TrimSpace(tfcInputBackendMigrateRemoteMultiToCloud),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error asking for state migration action: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if !migrate {
|
||||
return fmt.Errorf("Migration aborted by user.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Multi-state to single state.
|
||||
func (m *Meta) promptMultiToSingleCloudMigration(opts *backendMigrateOpts) error {
|
||||
migrate := opts.force
|
||||
|
@ -867,11 +912,26 @@ For more information on workspace naming, see https://www.terraform.io/docs/clou
|
|||
`
|
||||
|
||||
const tfcInputBackendMigrateMultiToSingle = `
|
||||
The previous backend %[1]q has multiple workspaces, but Terraform Cloud has been
|
||||
configured to use a single workspace (%[2]q). By continuing, you will only
|
||||
migrate your current workspace. If you wish to migrate all workspaces from the
|
||||
previous backend, use the 'tags' strategy in your workspace configuration block
|
||||
instead.
|
||||
The previous backend %[1]q has multiple workspaces, but Terraform Cloud has
|
||||
been configured to use a single workspace (%[2]q). By continuing, you will
|
||||
only migrate your current workspace. If you wish to migrate all workspaces
|
||||
from the previous backend, you may cancel this operation and use the 'tags'
|
||||
strategy in your workspace configuration block instead.
|
||||
|
||||
Enter "yes" to proceed or "no" to cancel.
|
||||
`
|
||||
|
||||
const tfcInputBackendMigrateRemoteMultiToCloud = `
|
||||
When migrating from the 'remote' backend to Terraform's native integration
|
||||
with Terraform Cloud, Terraform will automatically create or use existing
|
||||
workspaces based on the previous backend configuration's 'prefix' value.
|
||||
|
||||
When the migration is complete, workspace names in Terraform will match the
|
||||
fully qualified Terraform Cloud workspace name. If necessary, the workspace
|
||||
tags configured in the 'cloud' option block will be added to the associated
|
||||
Terraform Cloud workspaces.
|
||||
|
||||
Enter "yes" to proceed or "no" to cancel.
|
||||
`
|
||||
|
||||
const inputBackendMigrateEmpty = `
|
||||
|
|
Loading…
Reference in New Issue