Cloud integration requires input for migrations
We cannot programmatically migrate workspaces to Terraform Cloud without prompts, so `-input=false` should not be allowed in those cases. There are 4 scenarios where we need input from a user to complete migrating workspaces to Terraform Cloud. 1.) Migrate from a single local workspace to Terraform Cloud * Terraform config for a local backend. Implicit local (no backend specified) is fine. * `terraform init` and `terraform apply` * Change the Terraform config to use the cloud block * `terraform init -input=false` * You should now see an error message 2.) Migrate from a remote backend with a prefix to Terraform Cloud with tags * Create a workspace in Terraform Cloud manually. The name should include a prefix, like "app-one" * Have the terraform config use `backend "remote"` with a prefix set to "app-" * `terraform init` and `terraform apply` * Update the Terraform config to use a cloud block with `tags = ["app"]`. There should not be a prefix defined in the config now. * `terraform init -input=false` * You should now see an error message 3.) Migrate from multiple local workspaces to a single Terraform Cloud workspace * Create one or many local workspaces * `terraform init` and `terraform apply` in each * Change the Terraform config to use the cloud block * `terraform init -input=false` * You should now see an error message 4.) Migrate to Terraform Cloud and ask for a workspace name * Create several local workspaces * `terraform init` and `terraform apply` in each * Change the Terraform config to use the cloud block with tags * `terraform init -input=false` * You should now see an error message
This commit is contained in:
parent
a8972d82e9
commit
419676cb69
|
@ -1310,7 +1310,7 @@ func TestInit_inputFalse(t *testing.T) {
|
|||
}
|
||||
|
||||
errMsg := ui.ErrorWriter.String()
|
||||
if !strings.Contains(errMsg, "input disabled") {
|
||||
if !strings.Contains(errMsg, "interactive input is disabled") {
|
||||
t.Fatal("expected input disabled error, got", errMsg)
|
||||
}
|
||||
|
||||
|
|
|
@ -415,7 +415,7 @@ func (m *Meta) backendMigrateState_s_s(opts *backendMigrateOpts) error {
|
|||
// Abort if we can't ask for input.
|
||||
if !m.input {
|
||||
log.Print("[TRACE] backendMigrateState: can't prompt for input, so aborting migration")
|
||||
return errors.New("error asking for state migration action: input disabled")
|
||||
return errors.New(strings.TrimSpace(errInteractiveInputDisabled))
|
||||
}
|
||||
|
||||
// Confirm with the user whether we want to copy state over
|
||||
|
@ -773,6 +773,10 @@ func (m *Meta) backendMigrateState_S_TFC(opts *backendMigrateOpts, sourceWorkspa
|
|||
}
|
||||
|
||||
func (m *Meta) promptSingleToCloudSingleStateMigration(opts *backendMigrateOpts) (bool, error) {
|
||||
if !m.input {
|
||||
log.Print("[TRACE] backendMigrateState: can't prompt for input, so aborting migration")
|
||||
return false, errors.New(strings.TrimSpace(errInteractiveInputDisabled))
|
||||
}
|
||||
migrate := opts.force
|
||||
if !migrate {
|
||||
var err error
|
||||
|
@ -790,6 +794,10 @@ func (m *Meta) promptSingleToCloudSingleStateMigration(opts *backendMigrateOpts)
|
|||
}
|
||||
|
||||
func (m *Meta) promptRemotePrefixToCloudTagsMigration(opts *backendMigrateOpts) error {
|
||||
if !m.input {
|
||||
log.Print("[TRACE] backendMigrateState: can't prompt for input, so aborting migration")
|
||||
return errors.New(strings.TrimSpace(errInteractiveInputDisabled))
|
||||
}
|
||||
migrate := opts.force
|
||||
if !migrate {
|
||||
var err error
|
||||
|
@ -812,6 +820,10 @@ func (m *Meta) promptRemotePrefixToCloudTagsMigration(opts *backendMigrateOpts)
|
|||
|
||||
// Multi-state to single state.
|
||||
func (m *Meta) promptMultiToSingleCloudMigration(opts *backendMigrateOpts) error {
|
||||
if !m.input {
|
||||
log.Print("[TRACE] backendMigrateState: can't prompt for input, so aborting migration")
|
||||
return errors.New(strings.TrimSpace(errInteractiveInputDisabled))
|
||||
}
|
||||
migrate := opts.force
|
||||
if !migrate {
|
||||
var err error
|
||||
|
@ -839,6 +851,10 @@ func (m *Meta) promptNewWorkspaceName(destinationType string) (string, error) {
|
|||
message := fmt.Sprintf("[reset][bold][yellow]The %q backend configuration only allows "+
|
||||
"named workspaces![reset]", destinationType)
|
||||
if destinationType == "cloud" {
|
||||
if !m.input {
|
||||
log.Print("[TRACE] backendMigrateState: can't prompt for input, so aborting migration")
|
||||
return "", errors.New(strings.TrimSpace(errInteractiveInputDisabled))
|
||||
}
|
||||
message = `[reset][bold][yellow]Terraform Cloud requires all workspaces to be given an explicit name.[reset]`
|
||||
}
|
||||
name, err := m.UIInput().Input(context.Background(), &terraform.InputOpts{
|
||||
|
@ -854,6 +870,8 @@ func (m *Meta) promptNewWorkspaceName(destinationType string) (string, error) {
|
|||
}
|
||||
|
||||
func (m *Meta) promptMultiStateMigrationPattern(sourceType string) (string, error) {
|
||||
// This is not the first prompt a user would be presented with in the migration to TFC, so no
|
||||
// guard on m.input is needed here.
|
||||
renameWorkspaces, err := m.UIInput().Input(context.Background(), &terraform.InputOpts{
|
||||
Id: "backend-migrate-multistate-to-tfc",
|
||||
Query: fmt.Sprintf("[reset][bold][yellow]%s[reset]", "Would you like to rename your workspaces?"),
|
||||
|
@ -941,6 +959,12 @@ Migrating state from Terraform Cloud to another backend is not yet implemented.
|
|||
Please use the API to do this: https://www.terraform.io/docs/cloud/api/state-versions.html
|
||||
`
|
||||
|
||||
const errInteractiveInputDisabled = `
|
||||
Can't ask approval for state migration when interactive input is disabled.
|
||||
|
||||
Please remove the "-input=false" option and try again.
|
||||
`
|
||||
|
||||
const tfcInputBackendMigrateMultiToMultiPattern = `
|
||||
Enter a pattern with an asterisk (*) to rename all workspaces based on their
|
||||
previous names. The asterisk represents the current workspace name.
|
||||
|
|
Loading…
Reference in New Issue