Posts on Cloud,DevOps, Citrix,VMware and others. Also tracking my Continuous learning from Wintel to open source and development.
Words and views are my own and do not reflect on my companies views.
Disclaimer: some of the links on this site are affiliate links, if you click on them and make a purchase, I make a commission.

Saturday, August 4, 2018

HashiCorp Terraform 0.12 Preview: First-Class Expressions

This is the second post of the series highlighting new features in Terraform 0.12.

As part of the lead up to the release of Terraform 0.12, we are publishing a series of feature preview blog posts. The post this week is on first-class expressions.

Terraform uses expressions for dynamic configuration and dependencies. First-class expressions enable variables and operations to be performed outside of strings such as var.foo. In Terraform 0.11 and earlier all expressions were required to be part of interpolations in existing strings, such as "${var.foo}". This simple change has far-ranging benefits, covered in the blog examples.

Expressions with Lists and Maps

The improvements to expressions in Terraform 0.12 enable using lists and maps more directly with expressions. In versions of Terraform prior to 0.12, the HCL parser supports list and map syntax via [...] and {...} sequences, but it is not possible to use this syntax in conjunction with expressions. This is an artifact of the old HCL implementation having distinct phases for structure and interpolation and was a frequent source of confusion. To work around this limitation, Terraform provides the list and map functions for building lists inside interpolation expressions. The example below shows how this worked in Terraform 0.11 and earlier:

```hcl

Configuration for Terraform 0.11 and earlier

resource "aws_instance" "example" { # …

# The following works because the list structure is static vpcsecuritygroupids = ["${var.securitygroup1}", "${var.securitygroup_2}"]

Configuration for Terraform 0.12

This is also true of maps, allowing the {...} syntax to be used anywhere in an expression. This is generally expected behavior that unfortunately didn't work in previous Terraform releases, but now works as expected in Terraform 0.12.

Repeated Blocks

In 0.12, HCL also no longer accepts the following counter-intuitive configuration:

```

Configuration for Terraform 0.11 and earlier

Due to its attempts to flatten nested block structures down to JSON's information model, HCL would previously interpret the above as value = [{foo = "foo"},{bar = "bar"}]. While this is a logical consequence of how repeated blocks of the same type behave, it has often caused confusion for users. There are many other tricky behaviors of this sort, which cause the resulting data structure to not conform to the shape given in configuration.

In 0.12, HCL resolves this by making an explicit distinction between attributes and blocks. Attributes are single-assigned values using the assignment operator =. Blocks are repeated maps of key/value configuration pairs.

The above "weird" configuration now produces an error in HCL, because the attribute value may be defined only once. The error message will direct the user to the exact file, line, and column that the error occurred. It is valid to have more than one instance of the same block type:

```hcl

Configuration for Terraform 0.12

resource "awssecuritygroup" "example" { # …

# "ingress" is parsed as a block because there is no equals sign ingress { # .. }

ingress { # .. } } ```

Upgrade Guide

Terraform 0.12 will continue to support the string interpolation syntax from prior versions. As noted in the changes above, the use of the assignment operator = with repeated blocks will now produce an error and the = must be omitted. This is a breaking change but will have an intuitive error message pointing directly to the point of the error.

Next

First-class expressions will be released in Terraform 0.12, coming later this summer. To learn more about how to upgrade to Terraform 0.12, read the upgrade instructions which will be continuously updated as we get closer to releasing Terraform 0.12. If you have any feedback or concerns about these changes, please communicate with the Terraform team via the public mailing list.