Terraform 0.12.14 Released!

0.12.14 (November 13, 2019)


  • Terraform v0.12.0 included several changes to the Terraform language involving making expressions, type constraints, keywords, and references first-class in the language syntax, removing the need for placing thee items either in quoted strings or in interpolation syntax. Terraform v0.11 required these items to be quoted because the underlying language could not represent them any other way, while Terraform v0.12 expects them to be unquoted in order to improve readability.

    We have been accepting both forms for backward-compatibility with existing configurations and examples since the inititial v0.12.0 release. Having maintained compatibility for both forms for several versions we are now beginning the deprecation cycle for the old usage by having Terraform emit deprecation warnings.

    Terraform will still accept the older forms in spite of these warnings, so no immediate action is required. If your modules are targeting Terraform v0.12.0 and later exclusively, you can silence the warnings by removing the quotes, as directed in the warning message. In a future major version of Terraform, some of these warnings will be elevated to be errors.

    The summary of the warning for these situations will be one of the following:

    • Interpolation-only expressions are deprecated: an expression like "${foo}" should be rewritten as just foo.
    • Quoted type constraints are deprecated: In a variable block, a type constraint "map" should be written as map(string), "list" as list(string), and "string" as just string.
    • Quoted keywords are deprecated: In certain contexts that expect special keywords, such as when in provisioner blocks, the keyword should be unquoted.
    • Quoted references are deprecated: In the depends_on and ignore_changes meta-arguments, quoted references like "aws_instance.foo" should be rewritten without the quotes, e.g. as aws_instance.foo.

    The above changes are made automatically by the upgrade tool for users who are upgrading from Terraform 0.11. These warnings are intended to help those who are using Terraform for the first time at Terraform 0.12 but who may have found examples online that are written for older versions of Terraform, in order to guide towards the modern Terraform style.

  • The terraform output command would formerly treat no outputs at all as an error, exiting with a non-zero status. Since it’s expected for some root modules to have no outputs, the command now returns with success status zero in this situation, but still returns the error on stderr as a compromise to provide an explanation for why nothing is being shown.


  • config: Redundant interpolation syntax for attribute values and legacy (0.11-style) variable type constrants will now emit deprecation warnings. (#23348)
  • config: Keywords and references in depends_on, ignore_changes, and in provisioner when and on_failure will now emit deprecation warnings. (#23329)
  • command/output: Now treats no defined outputs as a success case rather than an error case, returning exit status zero instead of non-zero. (#23008] [#21136)
  • backend/artifactory: Will now honor the HTTP_PROXY and HTTPS_PROXY environment variables when appropriate, to allow sending requests to the Artifactory endpoints via a proxy. (#18629)


  • backend/remote: Filter environment variables when loading context for remote backend (#23283)
  • command/plan: Previously certain changes to lists would cause the list diff in the plan output to miss items. Now terraform plan will show those items as expected. (#22695)
  • command/show: When showing a saved plan file not in JSON mode, use the same presentation as terraform plan itself would’ve used. (#23292)
  • command/force-unlock: Return an explicit error when the local-filesystem lock implementation receives the wrong lock id. Previously it was possible to see either an incorrect error or no error at all in that case. (#23336)
  • core: Store absolute instance dependencies in state to allow for proper destroy ordering (#23252)
  • core: Ensure tainted status is maintained when a destroy operation fails (#23304)
  • config: transpose function will no longer panic when it should produce an empty map as its result. (#23321)
  • cli: When running Terraform as a sub-process of itself, we will no longer produce errant prefixes on the console output. While we don’t generally recommend using Terraform recursively like this, it was behaving in this strange way due to an implementation detail of how Terraform captures “panic” crashes from the Go runtime, and that subsystem is now updated to avoid that strange behavior. (#23281)
  • provisioners: Sanitize output to filter invalid utf8 sequences (#23302)
1 Like

Should note 12.15 was released right after to resolve a bug with using TF 0.11 syntax that yielded a message “Initialization required. Please see the error message above”

1 Like

Yep! Thanks @mikegreen.

I suspect I know the answer to this, but have to ask anyway:

While building a configuration generator this week, I accidentally produced HCL files with the resource type identifiers (not their names) unquoted, just bare strings (like ‘github_team’ from the GitHub provider).

resource github_team "example-team" {
  name = "example-team"

Terraform did not complain about this at all, either during validation, planning, or application. Is this just accidental, or did the 0.12 HCL changes bring this feature along for the ride?

Hi @kpfleming,

Having the labels unquoted is valid syntax, but is not idiomatic style. A future version of Terraform might have terraform fmt force quoting of those, to conform to the idiomatic style. Currently though, terrform fmt (and the rest of Terraform, for that matter) will accept both forms.

1 Like

Hi, folks!
Related Interpolation-only expressions are deprecated I would like to get some advises.
I have some tricks with the concatenation, like ${var.project_name}-foo-${var.user_name}
Well, now it’s deprecated. Should I use less readable code - format("%s-foo-%s",var.project_name,var.user_name) or I can turn linting off in my case?
Thank you!

1 Like

Hi @doctornkz,

The example you shared is not an interpolation-only expression, it’s a normal template expression containing interpolation sequences.

An interpolation-only expression would be something like:

  example = "${var.project_name}"

In the above, the "${ and }" serve no purpose and should therefore be removed.

However, your example includes a mixture of template components in your template expression:

  example = "${var.project_name}-foo-${var.user_name}"

There is no need to change anything about that expression. It’s already using the recommended language constructs to perform string interpolation.

1 Like

Thank you, Martin!
I am totally satisfied, will keep my code more readable.