Nebulaworks Insight Content Card Background - Andrew buchanan ground

Nebulaworks Insight Content Card Background - Andrew buchanan ground

Upgrade to Terraform 0.12: The Beginner's Guide

February 11, 2020 Matthew Shiroma

A concise step-by-step walkthrough of upgrading your Terraform projects to Terraform 0.12.

Recent Updates

Introduction

Terraform revolutionized the concept of infrastructure as code. By declaring your resources in the cloud in an easy to read language, managing what you have deployed has never been more streamlined until now. As with all popular coding languages, in the latter end of 2019 Terraform received a massive upgrade in its syntax and functionality, coined the 0.12 update. This update not only fixed numerous common errors in Terraform 0.11 but also overhauled the syntax for variable interpolation and output usage.

However, with the release of a major version, care needs to be taken when upgrading. While Terraform 0.11.14 includes commands to help with the upgrade, other factors like modules, state, providers, and Terraform 0.11 workarounds will need to be addressed. This blog post, Upgrade to Terraform 0.12: The Beginner’s Guide, will demystify those nuances.

Notable Changes in Terraform 0.12

For example, the common error for list interpolation:

(some list variable) = ["${var.someListVariable}"]

has now been fixed to now only needing this:

(some list variable) = "${var.someListVariable}"

Another fix is the strict enforcement between attributes and block assigning. Before Terraform 0.12, there was a loophole in utilizing map arguments and nested blocks by allowing for the interchanging of the two syntax types. An upgrade to Terraform 0.12 resolves this now by making both types of assigning to be consistent and will produce a verbose error indicating the inconsistency.

# Inconsistent
block_attribute {
  map_attribute {
    key = value
    ...
  }
}

# New enforcement
block_attribute {
  map_attribute = {
    key = value
    ...
  }
}

For a more detailed look at some of the new changes, they can be found here.

Important Nuances to 0.12

Before moving on to the upgrade process, a few points must be mentioned before considering the upgrade process:

Projects below Terraform 0.9

If your project is using Terraform 0.9 or lower, it is recommended to upgrade your project up to Terraform 0.9 first, before going directly to Terraform 0.11. This blog post will not cover upgrading to Terraform 0.9, but documentation for it can be found here.

Module Versions

One of the biggest areas for trouble when it comes to upgrading is the modules one is using for their infrastructure. While Terraform 0.12 does have backward compatibility with Terraform 0.11 syntax, if you have access to the module’s source, it is highly recommended to upgrade the modules to 0.12 as well. This is especially apparent when the module utilizes workarounds in Terraform 0.11 that no longer work in Terraform 0.12.

However, if you are utilizing a public module, it is important to see which version of the module supports Terraform 0.12. If there is such module, upgrading the module to that new module version is critical. If there is no such version yet, consider opening up an issue to bring it to the attention of the maintainers. If all else fails, creating a fork of the module and upgrading it yourself is viable, but be warned of fragmentation of the module versions.

Provider Versions

Like the modules, this is an important aspect of a Terraform project to keep in check when upgrading. With a new version of Terraform, the providers also get updated to support the update as well. As such, it is just simply looking in the change-logs to find the optimal version to utilize for Terraform 0.12.

The state file

Lastly, it is crucial to understand that state files made in Terraform 0.12 cannot be read with earlier Terraform versions. As such, it is important to have a backup of the state file before attempting the upgrade, just in case if anything goes wrong. I recommended trying the upgrade on a state file that is local on the computer so that all changes can be seen easily, compared if the state is stored remotely.

Pre-Requisites

In order to prepare your project for the upgrade to 0.12, the following must be met:

  1. Upgrading the project to use Terraform 0.11.14
  2. The infrastructure that is currently deployed is up to date with your configuration
  3. Have a version of Terraform 0.12 (any version will work, this guide will be using Terraform 0.12.1)
  4. The Terraform code to upgrade is stored in a source control environment (GitHub, GitLab, BitBucket, etc) using git

Helpful tip: If you want to have two versions of Terraform on your system and have the ability to change between them on the fly (if you have other projects utilizing older Terraform versions, I recommend looking into stow or terraform-switcher.)

Upgrade Process

Depending on what modules one is using, this process can go down in two ways:

If using local modules

  1. Navigate to the source of the module and upgrade that first (following the same general process)
  2. Once upgraded, be sure to then upgrade the configuration using the said module
  3. If all is good, merge changes from module and configuration into their own respective source controls

If using public modules

  1. Find the version of the module that supports Terraform 0.12
  2. Source that module’s version into your configuration
  3. Run the general process for updating your configuration
  4. If all is good, merge changes from configuration into source control

Once you have determined what your configuration is like, proceed to the general process while following either of the two paths above.

General Overview

  1. Navigate into the directory of your Terraform code

  2. Make sure your current directory has its state up to date and initialized properly (terraform init and terraform plan or terraform apply)

  3. Create a new branch, naming it to however your branching strategy outlines

cd yourCodeArea
git checkout -b branchName
  1. Make sure you are using terraform 0.11.14 by verifying the version and running the command terraform 0.12checklist
    • By default, this looks in the current directory and inspects all of the .tf and .tfvars files.
    • When you run this command, if there are no changes that would impact the update, the following will appear:
Looks good! We did not detect any problems that ought to be
addressed before upgrading to Terraform v0.12.

This tool is not perfect though, so please check the v0.12 upgrade
guide for additional guidance, and for next steps:
    https://www.terraform.io/upgrade-guides/0-12.html
  1. Repeat step 3 on all of the directories in your codebase, fixing any issues that may have arisen.
  2. Once everything looks good, switch over to terraform 0.12 (the version the blog will be using is 0.12.1) and run terraform init to reinitialize the directory with terraform 0.12
    • If this is done in a module, make sure to create a provider block (which is used temporarily in this process), otherwise, the following step will not work.
  3. After the directory is reinitialized, run the following command terraform 0.12upgrade, which will output this:
This command will rewrite the configuration files in the given directory so
that they use the new syntax features from Terraform v0.12, and will identify
any constructs that may need to be adjusted for correct operation with
Terraform v0.12.

We recommend using this command in a clean version control work tree, so that
you can easily see the proposed changes as a diff against the latest commit.
If you have uncommited changes already present, we recommend aborting this
command and dealing with them before running this command again.

Would you like to upgrade the module in the current directory?
  Only 'yes' will be accepted to confirm.

  Enter a value:
-----------------------------------------------------------------------------

Upgrade complete!

The configuration files were upgraded successfully. Use your version control
system to review the proposed changes, make any necessary adjustments, and
then commit.

If there are errors, running a terraform validate will help in pointing out trouble areas (like version specific fixes and new syntax usages)

  1. That’s it! You can then run a terraform plan to verify that the state has been properly migrated and all infrastructure from before should be the same now. To make sure the update went smoothly, I recommend the following extra steps:
    • Committing the changes to your new branch, and doing a git diff on the new code with the old code for any nuances
    • Running a terraform validate to confirm all new syntax is in check

If this command was done in a module, it is ok to delete the .terraform folder in there as well as the provider block, since they are no longer needed.

So what exactly did the two new terraform commands do?

I like you asked that! This process utilizes two commands that may seem a bit foreign for long time Terraform users.

The first command, terraform 0.12checklist, is a preview of what terraform 0.12upgrade does. It does not touch any of the configuration files, so it is designed to be a test run of what terraform 0.12upgrade does. However, for a starting point for the upgrade process, it is a good point to vet out potential issues.

The second command, terraform 0.12upgrade, does exactly what terraform 0.12checklist does, but this time, it will make changes to your Terraform files. Specifically, the only changes it will make to those files is updating all syntax from Terraform 0.11 to Terraform 0.12. An example of what one change could be is:

variableName = "${var.someValue}"

will turn into this, which is a new 0.12 syntax:

variableName = var.someValue

However, the command itself will not do this for all syntax instances, so depending on what your code contains, it may be necessary to go to said spots and convert them as needed. Regardless, this command helps get any code that is not using the new format to use said new format.

This will also produce a new file version.tf, where it locks the version of Terraform to be 0.12. This file can either be merged into another .tf file or removed altogether, although, having a specific version lock on the configuration is crucial. The reason is that all syntax from 0.12 is not backwards compatible with 0.11, so any deployments in Terraform must be done using Terraform 0.12.

Conclusion

Terraform brings new aspects to the table when it comes to infrastructure as code. Particulary with 0.12, it improved on its error messages, Terraform plans, and interpolation syntax, it is highly encouraged for teams to adopt the new version. Despite the large changes to the tool, the upgrade process has never been more streamlined. By following the steps above, you and your team will be more comfortable with the upgrade process.

I hope this blog post, Upgrade to Terraform 0.12: The Beginner’s Guide, helped anyone who wanted to advance their Terraform codebase. If you’d like to learn more about how to upgrade to Terraform 0.12 or have any inquiries about the adoption of Terraform, please reach out to us, as our team are experts at both open source and Enterprise HashiCorp tools.

Insight Authors

Matthew Shiroma, Cloud Engineer Matthew Shiroma Cloud Engineer
Nebulaworks - Wide/concrete light half gray

Looking for a partner with engineering prowess? We got you.

Learn how we've helped companies like yours.