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