diff --git a/states/statefile/version3_upgrade.go b/states/statefile/version3_upgrade.go index 64c3c1afb..753298ff0 100644 --- a/states/statefile/version3_upgrade.go +++ b/states/statefile/version3_upgrade.go @@ -7,6 +7,7 @@ import ( "strconv" "strings" + "github.com/hashicorp/hcl/v2/hclsyntax" "github.com/zclconf/go-cty/cty" ctyjson "github.com/zclconf/go-cty/cty/json" @@ -51,6 +52,13 @@ func upgradeStateV3ToV4(old *stateV3) (*stateV4, error) { // all of the modules are unkeyed. moduleAddr := make(addrs.ModuleInstance, len(msOld.Path)-1) for i, name := range msOld.Path[1:] { + if !hclsyntax.ValidIdentifier(name) { + // If we don't fail here then we'll produce an invalid state + // version 4 which subsequent operations will reject, so we'll + // fail early here for safety to make sure we can never + // inadvertently commit an invalid snapshot to a backend. + return nil, fmt.Errorf("state contains invalid module path %#v: %q is not a valid identifier; rename it in Terraform 0.11 before upgrading to Terraform 0.12", msOld.Path, name) + } moduleAddr[i] = addrs.ModuleInstanceStep{ Name: name, InstanceKey: addrs.NoKey, @@ -99,6 +107,13 @@ func upgradeStateV3ToV4(old *stateV3) (*stateV4, error) { var diags tfdiags.Diagnostics providerAddr, diags = addrs.ParseAbsProviderConfigStr(oldProviderAddr) if diags.HasErrors() { + if strings.Contains(oldProviderAddr, "${") { + // There seems to be a common misconception that + // interpolation was valid in provider aliases + // in 0.11, so we'll use a specialized error + // message for that case. + return nil, fmt.Errorf("invalid provider config reference %q for %s: this alias seems to contain a template interpolation sequence, which was not supported but also not error-checked in Terraform 0.11. To proceed, rename the associated provider alias to a valid identifier and apply the change with Terraform 0.11 before upgrading to Terraform 0.12", oldProviderAddr, instAddr) + } return nil, fmt.Errorf("invalid provider config reference %q for %s: %s", oldProviderAddr, instAddr, diags.Err()) } } else { @@ -110,6 +125,13 @@ func upgradeStateV3ToV4(old *stateV3) (*stateV4, error) { if oldProviderAddr != "" { localAddr, diags := addrs.ParseProviderConfigCompactStr(oldProviderAddr) if diags.HasErrors() { + if strings.Contains(oldProviderAddr, "${") { + // There seems to be a common misconception that + // interpolation was valid in provider aliases + // in 0.11, so we'll use a specialized error + // message for that case. + return nil, fmt.Errorf("invalid legacy provider config reference %q for %s: this alias seems to contain a template interpolation sequence, which was not supported but also not error-checked in Terraform 0.11. To proceed, rename the associated provider alias to a valid identifier and apply the change with Terraform 0.11 before upgrading to Terraform 0.12", oldProviderAddr, instAddr) + } return nil, fmt.Errorf("invalid legacy provider config reference %q for %s: %s", oldProviderAddr, instAddr, diags.Err()) } providerAddr = localAddr.Absolute(moduleAddr) diff --git a/website/upgrade-guides/0-12.html.markdown b/website/upgrade-guides/0-12.html.markdown index d5a3c432b..b4e9ca741 100644 --- a/website/upgrade-guides/0-12.html.markdown +++ b/website/upgrade-guides/0-12.html.markdown @@ -106,6 +106,31 @@ After all of the tasks are complete, run `terraform 0.12checklist` one more time to verify that everything is complete. If so, continue reading the following sections to complete the upgrade! +### Addendum: Invalid module names + +There is one additional pre-upgrade checklist item that the Terraform team did +not become aware of until after the release of Terraform v0.11.14, and thus +cannot be detected automatically by the checklist tool: renaming modules which +have names that start with digits. + +Terraform 0.11 inadvertently tolerated leading-digit names for modules as a +result of a validation bug, but Terraform 0.12 has corrected that bug and will +reject such module names. Unfortunately, module names are also recorded in +state snapshots and so a state snapshot created for a configuration with an +invalid module name will itself be invalid as far as Terraform 0.12 is +concerned. + +You can address this in a similar way to what the checklist tool suggests for +invalid resource names and provider aliases: + +* Rename the module in your configuration. +* Use `terraform state mv module.old module.new` _in Terraform 0.11.14_ to + update the state to use the new name instead of the old name. + +As with all of the pre-upgrade checklist items, be sure to run `terraform apply` +once more before upgrading in order to ensure that the latest state snapshot is +synchronized with the latest configuration. + ## Upgrading to Terraform 0.12 Before switching to Terraform 0.12, we recommend using Terraform v0.11.14 (or