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 {
|
||||
// Create a workspace
|
||||
options := tfe.WorkspaceCreateOptions{
|
||||
Name: tfe.String(name),
|
||||
}
|
||||
|
@ -517,12 +518,27 @@ func (b *Cloud) StateMgr(name string) (statemgr.Full, error) {
|
|||
}
|
||||
options.Tags = tags
|
||||
|
||||
options.TerraformVersion = tfe.String(tfversion.String())
|
||||
|
||||
workspace, err = b.client.Workspaces.Create(context.Background(), b.organization, options)
|
||||
if err != nil {
|
||||
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
|
||||
|
@ -948,6 +964,12 @@ const operationNotCanceled = `
|
|||
|
||||
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 (
|
||||
workspaceConfigurationHelp = fmt.Sprintf(
|
||||
`The 'workspaces' block configures how Terraform CLI maps its workspaces for this single
|
||||
|
|
Loading…
Reference in New Issue