cloud.StateMgr(): Set terraform version AFTER creating workspace
Previously, if the remote TFC/TFE instance doesn't happen to have a tool_version record whose name exactly matches the value of `tfversion.String()`, Terraform would be completely blocked from using the `terraform workspace new` command (when configured with the tags strategy) — the API would give a 422 to the whole create request. This commit changes the StateMgr() function to do the work in two passes; first create the workspace (which should work fine regardless), THEN update the Terraform version and print a warning to the terminal if it fails (which 99% of the time is a benign failure with little impact on your future CLI usage).
This commit is contained in:
parent
aace0015c2
commit
c99f5972de
|
@ -506,6 +506,7 @@ func (b *Cloud) StateMgr(name string) (statemgr.Full, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == tfe.ErrResourceNotFound {
|
if err == tfe.ErrResourceNotFound {
|
||||||
|
// Create a workspace
|
||||||
options := tfe.WorkspaceCreateOptions{
|
options := tfe.WorkspaceCreateOptions{
|
||||||
Name: tfe.String(name),
|
Name: tfe.String(name),
|
||||||
}
|
}
|
||||||
|
@ -517,12 +518,27 @@ func (b *Cloud) StateMgr(name string) (statemgr.Full, error) {
|
||||||
}
|
}
|
||||||
options.Tags = tags
|
options.Tags = tags
|
||||||
|
|
||||||
options.TerraformVersion = tfe.String(tfversion.String())
|
|
||||||
|
|
||||||
workspace, err = b.client.Workspaces.Create(context.Background(), b.organization, options)
|
workspace, err = b.client.Workspaces.Create(context.Background(), b.organization, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error creating workspace %s: %v", name, err)
|
return nil, fmt.Errorf("Error creating workspace %s: %v", name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attempt to set the new workspace to use this version of Terraform. This
|
||||||
|
// can fail if there's no enabled tool_version whose name matches our
|
||||||
|
// version string, but that's expected sometimes -- just warn and continue.
|
||||||
|
versionOptions := tfe.WorkspaceUpdateOptions{
|
||||||
|
TerraformVersion: tfe.String(tfversion.String()),
|
||||||
|
}
|
||||||
|
_, err := b.client.Workspaces.UpdateByID(context.Background(), workspace.ID, versionOptions)
|
||||||
|
if err != nil {
|
||||||
|
// TODO: Ideally we could rely on the client to tell us what the actual
|
||||||
|
// problem was, but we currently can't get enough context from the error
|
||||||
|
// object to do a nicely formatted message, so we're just assuming the
|
||||||
|
// issue was that the version wasn't available since that's probably what
|
||||||
|
// happened.
|
||||||
|
versionUnavailable := fmt.Sprintf(unavailableTerraformVersion, tfversion.String(), workspace.TerraformVersion)
|
||||||
|
b.CLI.Output(b.Colorize().Color(versionUnavailable))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a fallback error check. Most code paths should use other
|
// This is a fallback error check. Most code paths should use other
|
||||||
|
@ -948,6 +964,12 @@ const operationNotCanceled = `
|
||||||
|
|
||||||
const refreshToApplyRefresh = `[bold][yellow]Proceeding with 'terraform apply -refresh-only -auto-approve'.[reset]`
|
const refreshToApplyRefresh = `[bold][yellow]Proceeding with 'terraform apply -refresh-only -auto-approve'.[reset]`
|
||||||
|
|
||||||
|
const unavailableTerraformVersion = `
|
||||||
|
[reset][yellow]The local Terraform version (%s) is not available in Terraform Cloud, or your
|
||||||
|
organization does not have access to it. The new workspace will use %s. You can
|
||||||
|
change this later in the workspace settings.[reset]
|
||||||
|
`
|
||||||
|
|
||||||
var (
|
var (
|
||||||
workspaceConfigurationHelp = fmt.Sprintf(
|
workspaceConfigurationHelp = fmt.Sprintf(
|
||||||
`The 'workspaces' block configures how Terraform CLI maps its workspaces for this single
|
`The 'workspaces' block configures how Terraform CLI maps its workspaces for this single
|
||||||
|
|
Loading…
Reference in New Issue