github.com/hugorut/terraform@v1.1.3/website/docs/language/upgrade-guides/0-14.mdx (about)

     1  ---
     2  page_title: Upgrading to Terraform v0.14
     3  description: Upgrading to Terraform v0.14
     4  ---
     5  
     6  # Upgrading to Terraform v0.14
     7  
     8  Terraform v0.14 is a major release and so it includes some small changes in
     9  behavior that you may need to consider when upgrading. This guide is intended
    10  to help with that process.
    11  
    12  The goal of this guide is to cover the most common upgrade concerns and
    13  issues that would benefit from more explanation and background. The exhaustive
    14  list of changes will always be
    15  [the Terraform Changelog](https://github.com/hugorut/terraform/blob/v0.14/CHANGELOG.md).
    16  After reviewing this guide, we recommend reviewing the Changelog to check for
    17  specific notes about less-commonly-used features. This guide is also not
    18  intended as an overview of the new features in Terraform v0.14. This release
    19  includes other enhancements that don't need any special attention during
    20  upgrade, but those are described in the changelog and elsewhere in the
    21  Terraform documentation.
    22  
    23  This guide focuses on changes from v0.13 to v0.14. Terraform supports upgrade
    24  tools and features only for one major release upgrade at a time, so if you are
    25  currently using a version of Terraform prior to v0.13 please upgrade through
    26  the latest minor releases of all of the intermediate versions first, reviewing
    27  the previous upgrade guides for any considerations that may be relevant to you.
    28  
    29  In particular, Terraform v0.14 no longer includes the `terraform 0.13upgrade`
    30  command for automatically inserting
    31  [provider requirements](/language/providers/requirements)
    32  into existing modules, and the automatic mechanisms to upgrade legacy provider
    33  references in the Terraform state. You will need to successfully complete a
    34  `terraform apply` at least once under Terraform v0.13 before upgrading an
    35  existing configuration to Terraform v0.14.
    36  
    37  -> If you run into any problems during upgrading that are not addressed by the
    38  information in this guide, please feel free to start a topic in
    39  [The Terraform community forum](https://discuss.hashicorp.com/c/terraform-core),
    40  describing the problem you've encountered in enough detail that other readers
    41  may be able to reproduce it and offer advice.
    42  
    43  Upgrade guide sections:
    44  
    45  * [Before You Upgrade](#before-you-upgrade)
    46  * [Provider Dependency Lock File](#provider-dependency-lock-file)
    47  * [Concise Terraform Plan Output](#concise-terraform-plan-output)
    48  * [Sensitive Values in Plan Output](#sensitive-values-in-plan-output)
    49  * [Other important workflow changes](#other-important-workflow-changes)
    50  
    51  ## Before You Upgrade
    52  
    53  Terraform v0.14 does not support legacy Terraform state snapshot formats from
    54  prior to Terraform v0.13, so before upgrading to Terraform v0.14 you _must_
    55  have successfully run `terraform apply` at least once with Terraform v0.13
    56  so that it can complete its state format upgrades.
    57  
    58  When upgrading between major releases, we always recommend ensuring that you
    59  can run `terraform plan` and see no proposed changes on the previous version
    60  first, because otherwise pending changes can add additional unknowns into the
    61  upgrade process. Terraform v0.14 has the additional requirement of running
    62  `terraform apply`, as described above, because that allows Terraform v0.13 to
    63  commit the result of its automatic state format upgrades.
    64  
    65  ## Provider Dependency Lock File
    66  
    67  In Terraform v0.13 and earlier, the `terraform init` command would always
    68  install the newest version of any provider in the configuration that would
    69  meet the configured version constraints.
    70  
    71  That meant that unless the configuration author manually entered _exact_
    72  version constraints (for a particular version alone), a later provider release
    73  could potentially cause a change in behavior for an existing configuration even
    74  though the configuration itself had not changed.
    75  
    76  We believe that, as far as possible, the behavior of a configuration that has
    77  already been written and tested should remain consistent unless it is
    78  intentionally changed by its author, and that intentional changes should be
    79  represented in files that can be included in a version control system and
    80  code review process.
    81  
    82  To better meet that goal, Terraform v0.14 introduces a new
    83  [dependency lock file](/language/files/dependency-lock),
    84  which Terraform will generate automatically after running `terraform init`
    85  in the same directory as your configuration's root module. This file includes
    86  the specific version numbers selected for each provider, and also includes
    87  the package checksums for the selected version to help ensure that the
    88  provider packages you depend on are not changed in-place upstream,
    89  whether accidentally or maliciously.
    90  
    91  This new behavior is designed so that for most users it will not require
    92  a significant change in workflow. After running `terraform init` for the
    93  first time after upgrading you will find a new file `.terraform.lock.hcl`
    94  in your root module directory, and `terraform init` will automatically read
    95  and respect the entries in that file on future runs with no additional action
    96  on your part. We strongly recommend that you commit this file to your version
    97  control system, but if you do not then Terraform's behavior will be very similar to
    98  the old v0.13 behavior.
    99  
   100  There are some situations that require some further consideration though,
   101  and those are discussed in the following sections.
   102  
   103  ### Opting out of dependency locking
   104  
   105  We understand that not all teams share our belief that upgrades should always
   106  be represented as changes to the code in a version control repository. Those
   107  teams may have previously intentionally used a non-exact version constraint
   108  for one or more providers in order to automatically adopt any future provider
   109  releases and then make any necessary configuration changes in retrospect.
   110  
   111  You can continue with a model similar to the v0.13 behavior after upgrading
   112  to v0.14 by placing `.terraform.lock.hcl` in your version control system's
   113  "ignore" file, such as `.gitignore` for Git. In that case, Terraform will
   114  see the lock file in the same way as the internal index that Terraform v0.13
   115  would generate under the `.terraform` directory, preserving the selections
   116  only with in a particular working directory until you delete the file.
   117  
   118  With that said, we do recommend that teams consider carefully the benefits
   119  of a persistent lock file, and make a considered decision about which path
   120  to take. We believe that a lock file under version control will be the best
   121  choice for most teams, because we've seen this pattern used successfully in
   122  many other programming language ecosystems.
   123  
   124  ### In-house providers and internal mirrors
   125  
   126  Terraform v0.13 introduced a new hierarchical namespace for providers, which
   127  was an important pre-requisite for introducing a dependency lock file in
   128  v0.14 which can support a mixture of official, partner, community and in-house
   129  providers in a single configuration.
   130  
   131  If you followed the advice from the Terraform v0.13 upgrade guide about
   132  [assigning your in-house providers their own unique source addresses](/language/upgrade-guides/0-13#in-house-providers),
   133  and you're distributing your in-house providers to Terraform through one of
   134  the documented mechanisms, Terraform should handle selecting a version and
   135  recording its checksums in the same way for all of the providers you use.
   136  
   137  However, the full functionality of the lock file does depend on some
   138  information only available from a real provider registry, so there are some
   139  special considerations for providers installed from either filesystem or
   140  network mirrors:
   141  
   142  * Mirror sources don't provide package checksums that are signed by the original
   143    provider distributor, so by default `terraform init` will record only the
   144    checksum for the provider package on the platform you are currently using.
   145  
   146    For example, if you run `terraform init` on a macOS system and then commit
   147    the lock file, a collegue running `terraform init` on a Linux system may
   148    encounter a checksum error, because the mirror-based installation was only
   149    able to safely record the checksum for the package it actually installed.
   150  
   151    This problem doesn't arise for installation from a provider registry because
   152    the registry can provide signed checksums for all packages for a particular
   153    provider version, across all supported platforms.
   154  
   155    If you use mirrors exclusively in your environment and you use Terraform
   156    across a mixture of platforms then, in addition to making sure that your
   157    mirrors include packages for all of the necessary platforms, you may choose
   158    to use
   159    [the new `terraform providers lock` command](/cli/commands/providers/lock)
   160    to pre-enter the required lock file entries for all of the platforms you
   161    intend to use.
   162  
   163  * Terraform expects a particular version of a provider to have identical
   164    package checksums across all installation methods you work with in your
   165    team.
   166  
   167    For example, if you use direct installation from Terraform registries in
   168    your development environment but you use a mirror in your production
   169    automation, you must ensure that the packages available for a particular
   170    provider version in your mirror are identical to the official packages
   171    in the origin registry.
   172  
   173    If your internal mirrors intentionally have different packages than are
   174    available upstream, you must either use your internal mirrors consistently
   175    (so Terraform never uses or verifies an official package) or you must
   176    publish your own builds so that Terraform can understand your intent for
   177    them to be distinct.
   178  
   179    If you are only making minor or temporary changes to a provider, such as
   180    building for a platform that Terraform doesn't official support or including
   181    a bugfix patch that isn't yet in an upstream release, the simplest answer
   182    is to number your local build with semantic versioning _build metadata_,
   183    such as `v2.1.0+companyname.1` where `v2.1.0` is the upstream release you
   184    derived yours from, `companyname` is a short mnemonic for your organization,
   185    and `.1` is an internal build id that you can potentially increment if
   186    you need to make ongoing new builds from the same upstream version.
   187  
   188    If you are making more substantial changes to a provider, such as adding
   189    entirely new features that your modules depend on, it may be better to
   190    instead publish the provider under a separate namespace you control, such
   191    as publishing a fork of `hashicorp/aws` as `companyname/aws` in the public
   192    registry or `tf.example.com/companyname/aws` for in-house distribution only.
   193    This is a more drastic approach in that Terraform will understand your
   194    release as an entirely separate provider, but it also allows your modules
   195    to clearly indicate that they depend on the features of your fork rather
   196    than the features of the upstream release.
   197  
   198    In both cases the dependency lock file will see your releases as distinct
   199    from the upstream ones and thus expect the two to have a different set of
   200    checksums each.
   201  
   202  ### External module dependencies are not locked
   203  
   204  Although we do hope to eventually include a means to lock version selections
   205  for external modules in addition to providers, this new capability is limited
   206  only to providers in Terraform v0.14.
   207  
   208  Terraform modules have a different approach to distribution and versioning than
   209  Terraform providers, with many different supported installation methods that
   210  each require careful consideration in designing a dependency locking mechanism.
   211  
   212  If you wish to lock your module dependencies then for now you must continue
   213  to use the same strategy as for v0.13 and earlier: specify exact version
   214  constraints for modules distributed via a module registry, or use the
   215  source-type-specific mechanisms to lock to a particular version of module
   216  packages retrieved directly using other protocols.
   217  
   218  Note that Terraform also does not currently track checksums for external
   219  module dependencies. If you are concerned about the possibility of external
   220  modules being altered in-place without your knowledge, we recommend using
   221  modules only from sources directly under your control, such as a private
   222  Terraform module registry.
   223  
   224  ### The local provider cache directory
   225  
   226  As an implementation detail of automatic provider installation, Terraform
   227  has historically unpacked auto-installed plugins under the local cache
   228  directory in `.terraform/plugins`. That directory was only intended for
   229  Terraform's internal use, but unfortunately due to a miscommunication within
   230  our team it was inadvertently documented as if it were a "filesystem mirror"
   231  directory that you could place local providers in to upload them to
   232  Terraform Cloud.
   233  
   234  Unfortunately the implementation details have changed in Terraform v0.14 in
   235  order to move the authority for provider version selection to the new dependency
   236  lock file, and so manually placing extra plugins into that local cache directory
   237  is no longer effective in Terraform v0.14.
   238  
   239  We've included a heuristic in `terraform init` for Terraform v0.14 which should
   240  detect situations where you're relying on an unofficial provider manually
   241  installed into the cache directory and generate a warning like the following:
   242  
   243  ```
   244  Warning: Missing provider is in legacy cache directory
   245  
   246  Terraform supports a number of local directories that can serve as automatic
   247  local filesystem mirrors, but .terraform/plugins is not one of them because
   248  Terraform v0.13 and earlier used this directory to cache copies of provider
   249  plugins retrieved from elsewhere.
   250  
   251  If you intended to use this directory as a filesystem mirror for
   252  tf.example.com/awesomecorp/happycloud, place it instead in the following
   253  directory:
   254    terraform.d/plugins/tf.example.com/awesomecorp/happycloud/1.1.0/linux_amd64
   255  ```
   256  
   257  The error message suggests using the `terraform.d` directory, which is a
   258  local search directory originally introduced in Terraform v0.10 in order to
   259  allow sending bundled providers along with your configuration up to Terraform
   260  Cloud. The error message assumes that use-case because it was for Terraform
   261  Cloud in particular that this approach was previously mis-documented.
   262  
   263  If you aren't intending to upload the provider plugin to Terraform Cloud as
   264  part of your configuration, we recommend instead installing to one of
   265  [the other implied mirror directories](/cli/config/config-file#implied-local-mirror-directories),
   266  or you can explicitly configure some
   267  [custom provider installation methods](/cli/config/config-file#provider-installation)
   268  if your needs are more complicated.
   269  
   270  ## Concise Terraform Plan Output
   271  
   272  In Terraform v0.11 and earlier, the output from `terraform plan` was designed
   273  to show only the subset of resource instance attributes that had actually
   274  changed compared to the prior state.
   275  
   276  Although that made the output very concise, we heard from several users that
   277  the lack of context in the output had led to some misunderstandings that in
   278  turn caused production outages. We know that reviewing a Terraform plan can
   279  be a point of anxiety for those working on production infrastructure, so we
   280  responded to that feedback in Terraform v0.12 by having the plan output
   281  instead show the full context of each resource instance that has a planned
   282  action, and then use extra annotations (`+`, `-`, `~`) to mark the specific
   283  attributes that will change.
   284  
   285  Based on further feedback since the v0.12 release, we understand that the
   286  new detailed output has been very overwhelming for resource types that have
   287  a large number of attributes or deeply nested block structures. Terraform v0.14
   288  introduces a new compromise that aims to still address the concern about
   289  context while allowing better focus on the parts of each object that are
   290  changing.
   291  
   292  For this initial release, Terraform will omit from the plan output any
   293  attribute that has not changed, with the exception of a number of attribute
   294  names whose values often contain human-recognizable identifying information.
   295  When attributes or blocks are omitted, Terraform will always include a summary
   296  of what isn't included, to avoid ambiguity with an argument merely being unset.
   297  
   298  This is intended as an incremental step to improve the worst cases of verbose
   299  output in Terraform v0.12 and v0.13, but the compromises we made here may not
   300  be suitable for all situations. If you'd like to retain the fully-verbose
   301  output from Terraform v0.13, you can temporarily re-enable it by setting the
   302  environment variable `TF_X_CONCISE_DIFF=0` when you run Terraform.
   303  
   304  If you choose to opt out of the new concise mode, please
   305  [open a feature request issue](https://github.com/hugorut/terraform/issues/new?labels=enhancement%2C+new&template=feature_request.md)
   306  to let us know what you found lacking in the new output. We intend to continue
   307  iterating on the design tradeoffs here to find the best compromise to suit
   308  the needs of most users. We expect to remove the opt-out environment variable
   309  in Terraform v0.15.
   310  
   311  ## Sensitive Values in Plan Output
   312  
   313  In Terraform v0.13 and earlier, Terraform allowed provider authors to mark
   314  certain resource type attributes as being "sensitive", and similarly allowed
   315  module authors to mark certain output values as "sensitive". Terraform would
   316  then show the placeholder string `(sensitive value)` in the plan output,
   317  instead of the actual value.
   318  
   319  Terraform v0.14 introduces a more extensive version of that behavior where
   320  Terraform will track when you write an expression whose result is derived
   321  from a
   322  [sensitive input variable](/language/values/outputs#sensitive-suppressing-values-in-cli-output) or
   323  [sensitive output value](/language/values/variables#suppressing-values-in-cli-output),
   324  and so after upgrading to Terraform v0.14 you may find that more values are
   325  obscured in the Terraform plan output than would have been in Terraform v0.13.
   326  
   327  If a sensitive value (either derived from a sensitive input variable or a sensitive output variable) is used in another module output, that output must be marked `sensitive` as well to be explicit about this data being passed through Terraform:
   328  
   329  ```terraform
   330  variable "foo" {
   331    sensitive = true
   332  }
   333  
   334  output "bar" {
   335    value     = var.foo
   336    # sensitive must be true when referencing a sensitive input variable
   337    sensitive = true
   338  }
   339  ```
   340  
   341  There is also experimental behavior that will extend this sensitivity-awareness to attributes providers define as sensitive. You can enable this feature by activating the experiment in the `terraform` block:
   342  
   343  ```
   344  terraform {
   345    experiments = [provider_sensitive_attrs]
   346  }
   347  ```
   348  
   349  If you enable this experiment, attributes that are defined by a given _provider_ as sensitive will have the same sensitivity-tracking behavior as sensitive input values and outputs. For example, the [`vault_generic_secret`](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/data-sources/generic_secret) data source has an attribute `data` that is sensitive according to this provider's schema.
   350  
   351  ```
   352  # mod/main.tf
   353  
   354  terraform {
   355    experiments = [provider_sensitive_attrs]
   356  }
   357  
   358  data "vault_generic_secret" "foobar" {
   359    path = "secret/foobar"
   360  }
   361  
   362  output "token" {
   363    value = vault_generic_secret.foobar.data["token"]
   364    # a error will display if sensitive = true is not here
   365  }
   366  ```
   367  
   368  If you do not add `sensitive = true` to the output referencing that sensitive attribute, you will get an error:
   369  
   370  ```
   371  Error: Output refers to sensitive values
   372  
   373    on mod/main.tf line 6:
   374     6: output "token" {
   375  
   376  Expressions used in outputs can only refer to sensitive values if the
   377  sensitive attribute is true.
   378  ```
   379  
   380  For this feature we've taken the approach that it's better to be conservative
   381  and obscure _potentially-sensitive_ values at the expense of potentially also
   382  obscuring some values that aren't sensitive. Unfortunately this means that
   383  if you've written a module in a generic or dynamic way then Terraform may
   384  over-generalize which values are sensitive, leading to less helpful plan output.
   385  
   386  Due to the security implications of this feature, Terraform offers no direct
   387  way to opt out of this change. However, the obscuring of these values is done
   388  at the UI layer only and so you can still access the raw values, if needed,
   389  by saving your plan to an plan file and then asking Terraform to present it
   390  in machine-readable JSON format:
   391  
   392  ```
   393  terraform plan -out=tfplan
   394  terraform show -json tfplan
   395  ```
   396  
   397  Please note that the binary file `tfplan` and the JSON output produced from it
   398  can both include cleartext representations of sensitive values, so writing
   399  these to disk on a multi-user system or viewing the JSON output on-screen
   400  may cause those values to become visible to others.
   401  
   402  Sensitive values are also still saved in state snapshots stored in your
   403  configured backend. Use the access control and audit mechanisms offered by
   404  the remote system to control who can access that data.
   405  
   406  ## Other Important Workflow Changes
   407  
   408  ### Terraform Output Formatting
   409  
   410  We've modified the formatting of `terraform output` to match the formatting of `terraform show`.
   411  
   412  We consider the console output of Terraform human readable; specifically designed and optimized for operators and practitioners to review themselves. As a result we occasionally (maybe even regularly) intend to tweak that output to help improve consistency, clarity, actionability and more.
   413  
   414  If you rely on `terraform output` in automation, please use `terraform output -json`.