diff --git a/website/upgrade-guides/0-15.html.markdown b/website/upgrade-guides/0-15.html.markdown new file mode 100644 index 0000000000..fbee90b5b0 --- /dev/null +++ b/website/upgrade-guides/0-15.html.markdown @@ -0,0 +1,341 @@ +--- +layout: "language" +page_title: "Upgrading to Terraform v0.15" +sidebar_current: "upgrade-guides-0-15" +description: |- + Upgrading to Terraform v0.15 +--- + +# Upgrading to Terraform v0.15 + +Terraform v0.15 is a major release and so it includes some small changes in +behavior that you may need to consider when upgrading. This guide is intended +to help with that process. + +The goal of this guide is to cover the most common upgrade concerns and +issues that would benefit from more explanation and background. The exhaustive +list of changes will always be +[the Terraform Changelog](https://github.com/hashicorp/terraform/blob/v0.15/CHANGELOG.md). +After reviewing this guide, we recommend reviewing the Changelog to check for +specific notes about less-commonly-used features. + +This guide is also not intended as an overview of the new features in +Terraform v0.15. This release includes other enhancements that don't need any +special attention during upgrade, but those are described in the changelog and +elsewhere in the Terraform documentation. + +This guide focuses on changes from v0.14 to v0.15. Terraform supports upgrade +tools and features only for one major release upgrade at a time, so if you are +currently using a version of Terraform prior to v0.14 please upgrade through +the latest minor releases of all of the intermediate versions first, reviewing +the previous upgrade guides for any considerations that may be relevant to you. + +Unlike the previous few Terraform major releases, v0.15's upgrade concerns are +largely conclusions of deprecation cycles left over from previous releases, +many of which already had deprecation warnings in v0.14. If you previously +responded to those while using Terraform v0.14 then you hopefully won't need +to many any special changes to upgrade, although we still recommend reviewing +the content below to confirm, particularly if you see new errors or unexpected +behavior after upgrading from Terraform v0.14. + +-> If you run into any problems during upgrading that are not addressed by the +information in this guide, please feel free to start a topic in +[The Terraform community forum](https://discuss.hashicorp.com/c/terraform-core), +describing the problem you've encountered in enough detail that other readers +may be able to reproduce it and offer advice. + +Upgrade guide sections: + +* [Legacy Configuration Language Features](#legacy-configuration-language-features) +* [Alternative (Aliased) Provider Configurations](#alternative-provider-configurations) +* [Commands Accepting a Configuration Directory Argument](#commands-accepting-a-configuration-directory-argument) +* [Microsoft Windows Terminal Support](#microsoft-windows-terminal-support) +* [Other Minor Command Line Behavior Changes](#other-minor-command-line-behavior-changes) + +## Legacy Configuration Language Features + +Terraform v0.12 introduced new syntax for a variety of existing Terraform +language features that were intended to make the language easier to read and +write and, in some cases, to better allow for future changes to the language. + +Many of the old forms remained available but deprecated from v0.12 through to +v0.14, with these deprecations finally concluding in the v0.15 release. Those +who used the `terraform 0.12upgrade` command when upgrading from Terraform v0.11 +to v0.12 will have had these updated automatically, but we've summarized the +changes below to help with any remaining legacy forms you might encounter while +upgrading to Terraform v0.15: + +* The built-in functions `list` and `map` were replaced with first-class syntax + `[ ... ]` and `{ ... }` in Terraform v0.12, and we've now removed the + deprecated functions in order to resolve the ambiguity with the syntax used + to declare list and map type constraints inside `variable` blocks. + + If you need to update a module which was using the `list` function, you + can get the same result by replacing `list(...)` with `tolist([...])`. + For example: + + ```diff + - list("a", "b", "c") + + tolist(["a", "b", "c"]) + ``` + + If you need to update a module which was using the `map` function, you + can get the same result by replacing `map(...)` with `tomap([...])`. + For example: + + ```diff + - map("a", 1, "b", 2) + + tomap({ a = 1, b = 2 }) + ``` + + The above examples include the type conversion functions `tolist` and + `tomap` to ensure that the result will always be of the same type as + before. However, in most situations those explicit type conversions won't + be necessary because Terraform can infer the necessary type conversions + automatically from context. In those cases, you can just use the + `[ ... ]` or `{ ... }` syntax directly, without a conversion function. + +* In `variable` declaration blocks, the `type` argument previously accepted + v0.11-style type constraints given as quoted strings. This legacy syntax + is removed in Terraform v0.15. + + To update an old-style type constraint to the modern syntax, start by + removing the quotes so that the argument is a bare keyword rather than + a string: + + ```hcl + variable "example" { + type = string + } + ``` + + Additionally, if the previous type constraint was either `"list"` or + `"map`", add a type argument to specify the element type of the collection. + Terraform v0.11 typically supported only collections of strings, so in + most cases you can set the element type to `string`: + + ```hcl + variable "example" { + type = list(string) + } + + variable "example" { + type = map(string) + } + ``` + +* In `lifecycle` blocks nested inside `resource` blocks, Terraform previously + supported a legacy value `["*"]` for the `ignore_changes` argument, which + is removed in Terraform v0.15. + + Instead, use the `all` keyword to indicate that you wish to ignore changes + to all of the resource arguments: + + ```hcl + lifecycle { + ignore_changes = all + } + ``` + +* Finally, Terraform v0.11 and earlier required all non-constant expressions + to be written using string interpolation syntax, even if the result was + not a string. Terraform v0.12 introduced a less confusing syntax where + arguments can accept any sort of expression without any special wrapping, + and so the interpolation-style syntax has been redundant and deprecated + in recent Terraform versions. + + For this particular change we have not made the older syntax invalid, but + we do still recommend updating interpolation-only expressions to bare + expressions to improve readability: + + ```diff + - example = "${var.foo}" + + example = var.foo + ``` + + This only applies to arguments where the value is a single expression without + any string concatenation. You must continue to use the `${ ... }` syntax for + situations where you are combining string values together into a larger + string. + + The `terraform fmt` command can detect and repair simple examples of the + legacy interpolation-only syntax, and so we'd recommend running + `terraform fmt` on your modules once you've addressed any of the other + situations above that could block configuration parsing in order to update + your configurations to the typical Terraform language style conventions. + +## Alternative Provider Configurations + +Terraform's provider configuration scheme includes the idea of a "default" +(unaliased) provider configuration along with zero or more alternative +(aliased) provider configurations. + +TODO: Guide on the changes in this area. + +## Commands Accepting a Configuration Directory Argument + +A subset of Terraform's CLI commands have historically accepted a final +positional argument to specify which directory contains the root module of +the configuration, overriding the default behavior of expecting to find it +in the current working directory. + +However, the design of that argument was flawed in a number of ways due to +it being handled at the wrong level of abstraction: it only changed where +Terraform looks for configuration and not any of the other files that Terraform +might search for, and that could therefore violate assumptions that Terraform +configurations might make about the locations of different files, leading +to confusing error messages. It was also not possible to support this usage +pattern across all commands due to those commands using positional arguments +in other ways. + +To address these design flaws, Terraform v0.14 introduced a new global option +`-chdir` which you can use before the subcommand name, causing Terraform to +run the subcommand as if the given directory had been the current working +directory: + +```shellsession +$ terraform -chdir=example init +``` + +This command causes the Terraform process to actually change its current +working directory to the given directory before launching the subcommand, and +so now any relative paths accessed by the subcommand will be treated as +relative to that directory, including (but not limited to) the following key +directory conventions: + +* As with the positional arguments that `-chdir` replaces, Terraform will look + for the root module's `.tf` and `.tf.json` files in the given directory. + +* The `.tfvars` and `.tfvars.json` files that Terraform automatically searches + for, and any relative paths given in `-var-file` options, will be searched + in the given directory. + +* The `.terraform` directory which Terraform creates to retain the working + directory internal state will appear in the given directory, rather than + the current working directory. + +After treating the v0.14 releases as a migration period for this new behavior, +Terraform CLI v0.15 no longer accepts configuration directories on any +command except `terraform fmt`. (`terraform fmt` is special compared to the +others because it primarily deals with configuration files in isolation, +rather than modules or configurations as a whole.) + +If you built automation which previously relied on overriding the configuration +directory alone, you will need to transition to using the `-chdir` command line +option before upgrading to Terraform v0.15. + +Since the `-chdir` argument behavior is more comprehensive than the positional +arguments it has replaced, you may need to make some further changes in the +event that your automation was relying on the limitations of the old mechanism: + +* If your system depends on the `.terraform` directory being created in the + _real_ current working directory while using a root module defined elsewhere, + you can use the `TF_DATA_DIR` environment variable to specify the absolute + path where Terraform should store its working directory internal state: + + ```bash + TF_DATA_DIR="$PWD/.terraform" + ``` + +* If your system uses `.tfvars` or `.tfvars.json` files either implicitly found + or explicitly selected in the current working directory, you must either + move those variables files into the root module directory or specify your + files from elsewhere explicitly using the `-var-file` command line option: + + ```bash + terraform plan -var-file="$PWD/example.tfvars" + ``` + +As a special case for backward compatibility, Terraform ensures that the +language expression `path.cwd` will return the _original_ working directory, +before overriding with `-chdir`, so that existing configurations referring to +files in that directory can still work. If you want to refer to files in the +directory given in `-chdir` then you can use `path.root`, which returns the +directory containing the configuration's root module. + +## Microsoft Windows Terminal Support + +Until the first Windows 10 update, Microsoft Windows had a console window +implementation with an API incompatible with the virtual terminal approach +taken on all other platforms that Terraform supports. + +Previous versions of Terraform accommodated this by using an API translation +layer which could convert a subset of typical virtual terminal sequences into +corresponding Windows Console API function calls, but as a result this has +prevented Terraform from using more complex terminal features such as progress +indicators that update in place, menu prompts, etc. + +Over the course of several updates to Windows 10, Microsoft has introduced +virtual terminal support similar to other platforms and +[now recommends the virtual terminal approach for console application developers](https://docs.microsoft.com/en-us/windows/console/classic-vs-vt). +In response to that recommendation, Terraform v0.15 no longer includes the +terminal API translation layer and consequently it will, by default, produce +incorrectly-formatted output on Windows 8 and earlier, and on non-updated +original retail Windows 10 systems. + +If you need to keep using Terraform on an older version of Windows, there are +two possible workarounds available in the v0.15.0 release: + +* Run Terraform commands using the `-no-color` command line option to disable + the terminal formatting sequences. + + This will cause the output to be unformatted plain text, but as a result + will avoid the output being interspersed with uninterpreted terminal + control sequences. + +* Alternatively, you can use Terraform v0.15.0 in various third-party + virtual terminal implementations for older Windows versions, including + [ConEmu](https://conemu.github.io/), [Cmder](https://cmder.net/), + and [mintty](https://mintty.github.io/). + +Although we have no immediate plans to actively block running Terraform on +older versions of Windows, we will not be able to test future versions of +Terraform on those older versions and so later releases may contain +unintended regressions. We recommend planning an upgrade to a modern Windows +release on any system where you expect to continue using Terraform CLI. + +## Other Minor Command Line Behavior Changes + +Finally, Terraform v0.15 includes a small number of minor changes to the +details of some commands and command line arguments, as part of a general +cleanup of obsolete features and improved consistency: + +* Interrupting Terraform commands with your operating system's interrupt + signal (`SIGINT` on Unix systems) will now cause Terraform to exit with + a non-successful exit code. Previously it would, in some cases, exit with + a success code. + + This signal is typically sent to Terraform when you press + Ctrl+C or similar interrupt keyboard shortcuts in an interactive terminal, + but might also be used by automation in order to gracefully cancel a + long-running Terraform operation. + +* The `-lock` and `-lock-timeout` options are no longer available for the + `terraform init` command. Locking applies to operations that can potentially + change remote objects, to help ensure that two concurrent Terraform processes + don't try to run conflicting operations, but `terraform init` does not + interact with any providers in order to possibly effect such changes. + + These options didn't do anything in the `terraform init` command before, + and so you can remove them from any automated calls with no change + in behavior. + +* The `-verify-plugins` and `-get-plugins` options to `terraform init` are + no longer available. These have been non-functional since Terraform v0.13, + with the introduction of the new Terraform Registry-based provider installer, + because in practice there are very few operations Terraform can perform which + both require a `terraform init` but can also run without valid provider + plugins installed. + + If you were using these options in automated calls to `terraform init`, + remove them from the command line for compatibility with Terraform v0.15. + There is no longer an option to initialize without installing the + required provider plugins. + +* The `terraform destroy` command no longer accepts the option `-force`. This + was a previous name for the option in earlier Terraform versions, but we've + since adopted `-auto-approve` for consistency with the `terraform apply` + command. + + If you are using `-force` in an automated call to `terraform destroy`, + change to using `-auto-approve` instead.