196 lines
10 KiB
Plaintext
196 lines
10 KiB
Plaintext
---
|
|
page_title: Upgrading to Terraform v1.1
|
|
description: Upgrading to Terraform v1.1
|
|
---
|
|
|
|
# Upgrading to Terraform v1.1
|
|
|
|
Terraform v1.1 is the first minor release after establishing a compatibility
|
|
baseline in Terraform v1.0, and so this release should not require any
|
|
unusual upgrade steps for most users.
|
|
|
|
However, if you are upgrading from a version earlier than v1.0 then please
|
|
refer to [the Terraform v1.0 upgrade guide](/language/upgrade-guides/1-0) for how to upgrade through
|
|
the v0 releases to reach the v1 release series. Because v1.1 is
|
|
backward-compatible with the v1.0 series, you can upgrade directly to the
|
|
latest v1.1 release, skipping the v1.0 series entirely, at any point where the
|
|
v1.0 upgrade guide calls for upgrading to Terraform v1.0.
|
|
|
|
Terraform v1.1 continues to honor
|
|
[the Terraform v1.0 Compatibility Promises](/language/v1-compatibility-promises),
|
|
but there are some behavior changes outside of those promises that may affect a
|
|
small number of users, described in the following sections.
|
|
|
|
* [Terraform requires macOS 10.13 High Sierra or later](#terraform-requires-macos-1013-high-sierra-or-later)
|
|
* [Preparation for removing Azure AD Graph support in the AzureRM Backend](#preparation-for-removing-azure-ad-graph-support-in-the-azurerm-backend)
|
|
* [Interpretation of remote file paths in the `remote-exec` and `file` provisioners](#interpretation-of-remote-file-paths-in-the-remote-exec-and-file-provisioners)
|
|
* [Changes to `terraform graph`](#changes-to-terraform-graph)
|
|
* [Changes to `terraform state mv`](#changes-to-terraform-state-mv)
|
|
* [Provider checksum verification in `terraform apply`](#provider-checksum-verification-in-terraform-apply)
|
|
|
|
## Terraform requires macOS 10.13 High Sierra or later
|
|
|
|
As operating system vendors phase out support for older versions of their
|
|
software, the Terraform team must also phase out support in order to focus
|
|
on supporting newer releases.
|
|
|
|
With that in mind, the official releases of Terraform v1.1 now require
|
|
macOS 10.13 High Sierra or later. Earlier versions of macOS are no longer
|
|
supported, and Terraform CLI behavior on those earlier versions is undefined.
|
|
|
|
## Preparation for removing Azure AD Graph support in the AzureRM Backend
|
|
|
|
[Microsoft has announced the deprecation of Azure AD Graph](https://docs.microsoft.com/en-us/graph/migrate-azure-ad-graph-faq),
|
|
and so Terraform v1.1 marks the first phase of a deprecation process for
|
|
that legacy system in [the AzureRM state storage backend](/language/settings/backends/azurerm).
|
|
|
|
During the Terraform v1.1 release the default behavior is unchanged, but you
|
|
can explicitly opt in to Microsoft Graph by setting
|
|
`use_microsoft_graph = true` inside your `backend "azurerm` block and then
|
|
reinitializing your working directory with `terraform init -reconfigure`.
|
|
|
|
In Terraform v1.2 we plan to change this argument to default to `true` when
|
|
not set, and so we strongly recommend planning to migrate to Microsoft Graph
|
|
in the near future to prepare for the final removal of Azure AD Graph support
|
|
in a later Terraform release. However, no immediate change is required before
|
|
upgrading to Terraform v1.1.
|
|
|
|
## Interpretation of remote file paths in the `remote-exec` and `file` provisioners
|
|
|
|
When using Terraform's built-in `remote-exec` and `file` provisioners, there
|
|
are two situations where Terraform internally uses
|
|
[Secure Copy Protocol](https://en.wikipedia.org/wiki/Secure_copy_protocol)
|
|
(SCP) to upload files to the remote system at a configuration-specified
|
|
location:
|
|
|
|
* For [the `file` provisioner](/language/resources/provisioners/file),
|
|
the primary functionality is to upload a file using SCP, and the
|
|
`destination` argument specifies the remote path where the file is to be
|
|
written.
|
|
* For [the `remote-exec` provisioner](/language/resources/provisioners/remote-exec),
|
|
internally the provisioner works by uploading the given scripts to files
|
|
on the remote system and then executing them. By default the provisioner
|
|
selects a temporary filename automatically, but a module author can
|
|
potentially override that location using the `script_path` argument in the
|
|
associated [`connection` block](https://www.terraform.io/language/resources/provisioners/connection).
|
|
|
|
If you are not using either of the specific arguments mentioned above, no
|
|
configuration changes will be required to upgrade to Terraform v1.1.
|
|
|
|
These provisioners both passing the specified remote paths to the `scp` service
|
|
program on the remote system. In Terraform v1.0 and earlier, the provisioners
|
|
were passing the paths to `scp` in a way that was inadvertently subject to
|
|
_shell expansion_. That inadvertently allowed for convenient shorthands
|
|
such as `~/example` and `$HOME/example` to write into the target user's
|
|
home directory, but also offered an undesirable opportunity for accidental
|
|
remote code execution, such as `$(arbitrary-program)`.
|
|
|
|
In Terraform v1.1 both of the above remote path arguments are passed _verbatim_
|
|
to the remote `scp` service, without any prior shell expansion. For that reason,
|
|
shell-defined expansion tokens such as `~` and environment variable references
|
|
will no longer be evaluated.
|
|
|
|
By default, the OpenSSH server and the program `scp` together already interpret
|
|
relative paths as relative to the target user's home directory, and so
|
|
module authors can specify relative paths without any special metacharacters
|
|
in order to request uploading into that default location:
|
|
|
|
```hcl
|
|
provisioner "file" {
|
|
source = "local.txt"
|
|
destination = "remote.txt"
|
|
}
|
|
```
|
|
|
|
If you maintain a module that was depending on expansion of `~/`, `$HOME/`,
|
|
`${HOME}`/ or similar, remove that prefix so that your module instead specifies
|
|
just a relative path.
|
|
|
|
This is an intentional compatibility regression which we accepted after due
|
|
consideration of
|
|
[the pragmatic exceptions to our compatibility promises](/language/v1-compatibility-promises#pragmatic-exceptions).
|
|
Specifically, this behavior offered an unintended and non-obvious avenue for
|
|
arbitrary code execution on the remote system if either of the above arguments
|
|
were populated from outside input, and an alternative approach is available
|
|
which doesn't have that drawback, and this is therefore justified on security
|
|
grounds.
|
|
|
|
## Changes to `terraform graph`
|
|
|
|
The `terraform graph` command exists to help with debugging and so it
|
|
inherently exposes some of Terraform Core's implementation details. For that
|
|
reason it isn't included in the v1.0 Compatibility Promises, but we still
|
|
aim to preserve its behavior in spirit even as Terraform Core's internal
|
|
design changes.
|
|
|
|
In previous releases, `terraform graph` exposed the implementation detail that
|
|
Terraform internally knows how to build graph types called "validate" and
|
|
"eval", but Terraform Core no longer exposes those graph types externally
|
|
and so consequently the graph command will no longer accept the options
|
|
`-type=validate` or `-type=eval`.
|
|
|
|
You can see a similar result to what those graph types would previously
|
|
produce by generating a _plan_ graph, which is the default graph type and
|
|
therefore requires no special `-type=...` option.
|
|
|
|
## Changes to `terraform state mv`
|
|
|
|
Terraform's local state storage backend supports a number of
|
|
[legacy command line options](/language/settings/backends/local#command-line-arguments)
|
|
for backward-compatibility with workflows from much older versions of Terraform,
|
|
prior to the introduction of Backends.
|
|
|
|
Those options are not supported when using any other backend, but for many
|
|
commands they are simply silently ignored rather than returning an error.
|
|
|
|
Because `terraform state mv` has some extra use-cases related to migrating
|
|
between states, it historically had some slightly different handling of those
|
|
legacy options, but was not fully consistent.
|
|
|
|
From Terraform v1.1, the behavior of these options has changed as follows:
|
|
|
|
* The `-state=...` argument is allowed even when a remote backend is specified
|
|
in the configuration. If present, it forces the command to work in local
|
|
mode.
|
|
* The `-backup=...` and `-backup-out=...` options are allowed only if either
|
|
the local backend is the configuration's selected backend _or_ if you
|
|
specify `-state=...` to force local state operation. These options will now
|
|
return an error if used against a remote backend, whereas previous Terraform
|
|
versions ignored them entirely in that case.
|
|
|
|
There are no breaking changes to `terraform state mv`'s normal usage pattern,
|
|
without any special options overriding the state storage strategy.
|
|
|
|
## Provider checksum verification in `terraform apply`
|
|
|
|
This section applies only to situations where you might generate a saved
|
|
plan file using `terraform plan -out=tfplan` and then separately apply it
|
|
using `terraform apply tfplan`.
|
|
|
|
You do not need to consider this section unless you are using a custom
|
|
Terraform provider which somehow modifies its own provider package contents
|
|
during execution. That is hypothetically possible, but not true in practice for
|
|
any publicly-available providers we are aware of at the time of writing this
|
|
guide.
|
|
|
|
Our design intent for this two-step run workflow is that the saved plan
|
|
records enough information for Terraform to guarantee that it's running
|
|
against an identical set of providers during the apply step as it was during
|
|
the plan step, because otherwise the different provider plugins may disagree
|
|
about the meaning of the planned actions.
|
|
|
|
However, prior versions of Terraform verified consistency only for the main
|
|
executable file representing a provider plugin, and didn't consider other
|
|
files that might appear alongside in the plugin package. Terraform v1.1 now
|
|
uses the same strategy for provider checking during apply as it does when
|
|
verifying provider consistency against
|
|
[the dependency lock file](/language/files/dependency-lock)
|
|
during `terraform init`, which means `terraform apply` will return an error
|
|
if it detects that _any_ of the files in a provider's plugin package have
|
|
changed compared to when the plan was created.
|
|
|
|
In the unlikely event that you _do_ use a self-modifying provider plugin,
|
|
please consider other solutions to achieve the goals which motivated that,
|
|
which do not involve the provider modifying itself at runtime. If you aren't
|
|
sure, please open a GitHub issue to discuss your use-case.
|