HashiCorp Terraform 0.4

We are releasing Terraform 0.4. Terraform is a tool for safely and efficiently building, combining, and launching infrastructure.

Terraform 0.4 is our biggest release ever. We're shipping with multiple major features as well as a vast improvement to support for AWS. Terraform 0.4 had the most community involvement ever with 80 contributors, including new core committers Paul Hinze and Clint Shryock.

Feature highlights for Terraform 0.4:

»New Provider: Docker

Terraform 0.4 is the first release to ship with support for managing the lifecycle of Docker containers. The Terraform Docker provider talks to Docker over the Docker server API, making it instantly compatible with multiple hosts, cluster management tools, as well as the simple single server case.

Docker fits right into the Terraform model, allowing you to manage your containers in much the same way as you manage your VM instances or other resources:

resource "docker\_container" "web" {
    image = "${docker\_image.ubuntu.latest}"
    count = 5

resource "docker\_image" "ubuntu" {
    name = "ubuntu:latest"

The major features of configuring Docker containers are supported with this release, but many of the tunables are not yet supported. We'll be adding these in upcoming releases.

The Docker provider is fully documented here.

»New Provider: OpenStack

Terraform 0.4 ships with support for OpenStack. The OpenStack provider ships both the v2 and v1 OpenStack API, and supports over a dozen resources out of the gate including instances, floating IPs, block storage, keypairs, and more.

The OpenStack provider fits into the existing Terraform model nicely:

\# Configure the OpenStack Provider
provider "openstack" {
    user\_name  = "admin"
    tenant\_name = "admin"
    password  = "pwd"
    auth\_url  = "http://myauthurl:5000/v2.0"

»Create a web server

resource "openstack\_compute\_instance\_v2" "test-server" {

The OpenStack provider is fully documented here.

»Feature: Targeted Operations

Targeted operations is a new feature in Terraform to enhance the workflow and give operators more control to ensure that only changes they want to happen will happen. Targeted operations allow users to now target one or more resources with a refresh, plan, apply, or destroy. This means that only the resources targeted will be modified, even if others would need to be modified to reach your complete desired state.

As an example use case: an operator may make major changes to the Terraform configuration, but you only want to roll out the web server updates now. You can now do this with targeted operations, delaying the other changes until a future time.

The syntax is shown below:

$ terraform apply -target=aws\_instance.web

Targeted operations are available on refresh, plan, apply, and destroy.

»Feature: Remote Modules

The previous release of Terraform, Terraform 0.3, introduced modules. Modules are a unit of encapsulation for Terraform that allow operators to share components of their infrastructure and treat them as a single unit with inputs and outputs.

Terraform 0.4 goes one step further to improve collaboration with remote modules. Remote modules are a way to access only the resulting outputs of an independent Terraform run.

Remote modules are a way for teams within an organization to share infrastructure resources in a read-only way without other teams being able to build or modify that infrastructure. An example: a team builds and maintains a highly-available database cluster, and other teams can access the URL and access information via remote modules without ever risking modifying that infrastructure.

Remote modules are accessed as a standard Terraform resource. An example is shown below:

resource "terraform\_remote\_state" "vpc" {
    backend = "atlas"
    config {
        path = "hashicorp/vpc-prod"

resource "aws\_instance" "foo" {
    # ...
    subnet\_id = "${terraform\_state.vpc.output.subnet\_id}"

As you can see from the above example, this allows separate teams to maintain different parts of the infrastructure, and for other teams to access these.

»Command: Taint

Terraform 0.4 introduces a new top-level CLI command: terraform taint.

The taint command enables you to explicitly taint a resource. Tainted resources are marked for destroy/recreate on the next plan or apply. This lets you force recreate existing resources that Terraform might have otherwise not have changed.

There are a few use cases for this. One use case is to force the re-running of provisioners, which only run on creation time within Terraform. Another is to simply recycle the resource, such as potentially getting better hardware on Amazon EC2.

Prior to the taint command, you'd have to remove the resource from the config, then re-add it. This is now all possible from the command-line. Syntax example is shown below:

$ terraform taint aws\_instance.web

The taint command documentation is here.

»Updates to Terraform Configuration

The Terraform configuration received some major improvements in Terraform 0.4: math operations are now available, a handful of new functions have been introduced, and a new type of variable known as a "self" variable exists.

Math operations let you do math within configuration interpolations. For example, count.index is typically zero-indexed, but if you wanted to name your instances starting with a one-indexed number, it is now trivial:

resource "aws\_instance" "web" {
    count = 5
    tags {
        Name = "web-${count.index+1}"

Math operations aren't limited to literal numbers. You can also do things like this: ${count.index+aws_instance.tags.number}. This will result in a runtime error if the value can't be converted to a number.

In addition to math operations, three new functions are now available in the configuration: format, replace, and split. Each probably does what you expect and is documented. split is a notable adition to the configuration, because along with join (introduced in 0.3), it is now possible to transfer lists of data between modules and as variable inputs to a Terraform configuration.

We'd still like to add first-class support for lists at some point but this is a strong workaround in the meantime.

Finally, self variables are new to Terraform configurations. Self variables let you reference the attributes of your own resource. These are currently only available within provisioners. Example:

resource "aws\_instance" "web" {
    provisioner "local-exec" {
        command = "echo ${self.private\_ip\_address}"

Self variables solve the problem of referencing your own resource in provisioners in both single and multi-count cases without creating a cycle in the Terraform graph.

»AWS Improvements and Features

For the duration of Terraform 0.4 development, one core comitter has worked full time on improving AWS support. This effort has been very successful, with a number of impactful changes:

  • Tagging support for AWS resources in Terraform.

  • Focus on bug fixes and features to make sure the load balancer, autoscale group, launch configuration workflow works really well.

  • Non-destructive updates to RDS.

  • Fix numerous "dependency violation" issues that were source of update inconsistencies in Terraform as a result of the eventually consistent nature of AWS.

  • Complete migration to the official AWS SDK, giving Terraform full access to every AWS API. This will let us complete AWS support over future releases.

For 0.4, we focused on major features (such as tagging) and bug fixes across existing supported resources. For upcoming versions, we're going to focus on completing support for AWS by adding resources.

»And so much more...

New Provider: DNSMadeEasy. Configure your DNS through DNSMadeEasy.

SSH Agent Support for remote-exec. By specifying agent = true, the remote-exec provisioner will now use your local SSH agent to connect to the remote host.

Continuous state saving. Terraform used to only persist state updates at the end of a Terraform run. If Terraform crashed for any reason before this (computer shut down abruptly, kernel killed it due to memory pressure, etc.), then it would result in a loss of state. Terraform now persists state after every resource change, minimizing the window where state loss can happen.

Dozens of bug fixes. In addition to everything above, there have been dozens of bug fixes across Terraform from core to the individual providers. Please see the full CHANGELOG for more information.


At HashiCorp, we strive for our 0.4 releases to be very stable, both from a technical and user experience perspective. Terraform 0.4 follows this trend: we're confident in the internal stability of the tool and have begun shipping features that focus on user experience, such as math operations, targeted operations, new providers, etc.

With multiple core committers now working on Terraform full time, Terraform development has accelerated to a lightning pace, and we're already well under way for 0.5 features. We're looking forward to bringing you these updates soon.

Go download it and give it a try!

Sign up for the latest HashiCorp news

By submitting this form, you acknowledge and agree that HashiCorp will process your personal information in accordance with the Privacy Policy.