Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Terraform 0.12 Release: New HCL Syntax, Improved Error Messages, and Upgrade Tooling

Terraform 0.12 Release: New HCL Syntax, Improved Error Messages, and Upgrade Tooling

At the recent HashiConf EU 2019 event, Kristin Laemmert, Terraform core developer at HashiCorp, talked about the new release of Terraform 0.12, which includes updates to the HashiCorp Configuration Language (HCL), such as first-class expression syntax, value types, loops, dynamic blocks, and conditional expression improvements. Terraform 0.12 also has improved error messages which contain additional context and a pointer to where the problem is, and the output to a terraform plan now renders in a more readable format. Terraform 0.12 is not 100% backwards compatible, but comes with an upgrade and validation tool.

In previous versions of Terraform, the configuration language is composed by the HCL and the HashiCorp Interpolation Language (HIL). HCL handles the attribute and block syntax for configuration files, like a resource block to define an EC2 instance, and HIL handles the string interpolation ("${}"), allowing users to use variables inside a string text, for instance, when defining a server name like "server-name-${count.index}." In version 0.12, Terraform merges the HCL and HIL into a single library, introducing an improved expression system and new features. Users now no longer need string interpolation when referencing a resource name or a variable, and, for example, this allows users to write the configuration of location = "${var.location}" instead as location = var.location, without the quotes and the dollar sign.

The new HCL version also improves the conditional expressions. In Terraform 0.11, a user could define a condition with the following syntax:

In Terraform 0.12, code no longer needs string interpolation, and an empty bracket represents an empty list. Also, an empty string can be represented with a null value type–this is a new feature, as in previous versions every value was a string. The same code block will look like this in 0.12:

With the introduction of a new version of HCL, HashiCorp is not only changing the language but also adding new expressions like the for and for_each to iterate within a template. HashiCorp has also added a new keyword called dynamic, which can be used to construct nested blocks in conjunction with the for and for_each expressions. Although loop expressions are not supported for modules and resources yet, a user can reduce template lines by using these new expressions.

To demonstrate these new expressions, Laemmert showed the example of a Docker container resource in 0.11:

To address this situation, Laemmert provided an example of a better template version in 0.12:

Other improvements include improved error messages and better formatting of the output of the terraform plan command. Before 0.12, when Terraform detected error within the configuration, a user didn’t get much information about what was wrong. For example, if the resource block name contained invalid characters, the error message only said that the template had invalid characters somewhere. Now, in 0.12, users receive additional context like the line number, a code snippet, and a detailed error message:

Error: Invalid output name

  on line 9, in output "VMs RDP acces":
   9: output "VMs RDP acces" {

A name must start with a letter and may contain only letters, digits,
underscores, and dashes.

An output plan in Terraform 0.12 now has a defined structured that makes it more readable for users. Instead of a simple key/value pairs list, the output now has more information and integrates with value types and a nested structure when applicable:

Terraform will perform the following actions:

  # azurerm_public_ip.lbpip will be updated in-place
  ~ resource "azurerm_public_ip" "lbpip" {
        allocation_method            = "Dynamic"
      ~ domain_name_label            = "coolapplb" -> "coolapp"
        fqdn                         = ""
        id                           = "/subscriptions/aaa333f9-3b00-475c-a8b8-123af2c200b0/resourceGroups/coolapp/providers/Microsoft.Network/publicIPAddresses/rg-ip"
        idle_timeout_in_minutes      = 4
        ip_address                   = ""
        ip_version                   = "IPv4"
        location                     = "southcentralus"
        name                         = "rg-ip"
        public_ip_address_allocation = "Dynamic"
        resource_group_name          = "coolapp"
        sku                          = "Basic"
        tags                         = {}
        zones                        = []

Lastly, Laemmert shared several upgrade resources for users who want to migrate their templates to the new version. Terraform 0.12 is not 100% backwards compatible but comes with an upgrade and validation tool. HashiCorp published a post with options on how to migrate from a previous version. Microsoft also has a migration guide specific to Azure Terraform templates, and Ali Mukadam, technical director at Oracle, shared his lessons learned when migrating to version 0.12 with the Oracle Container Engine provider. Popular Terraform posts and books were also impacted by the new release of Terraform. Laemmert closed by saying that the HashiCorp team are still working on several new features for upcoming Terraform versions.

This tour of Terraform 0.12 described a few highlights only. The detailed changelog is on GitHub, and HashiCorp has already updated the Terraform documentation.

Rate this Article