website: Terraform v0.15 upgrade guide first draft
As usual, we'll continue to iterate on this based on feedback and questions during the beta period, but this is a first draft intended to help those who are trying out the first beta.
This commit is contained in:
parent
e5a7586559
commit
9508ff2630
|
@ -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.
|
Loading…
Reference in New Issue