Terraform 0.3

Terraform 0.3

Oct 14 2014    Mitchell Hashimoto

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

Terraform 0.3 is a massive release filled with both features and a wealth of stability improvements. If you've been waiting for a strong version to try Terraform, this is the version to use.

This version of Terraform introduces modules, dynamic resource counts, user input for parameterization, JSON-based state, provisioner output, improvements to existing providers, and much more.

In this post, we'll highlight the major features added, as well as show videos of Terraform showcasing the new features.

Demo Videos

The videos below showcase a lot of the features in Terraform 0.3. We go over the major features later in the blog post.


Modules are a way in Terraform to organize a set of Terraform configurations into a reusable, distributable package. In the demo video above, the Consul Terraform module is used to quickly initialize and start an infrastruture.

Using modules is simple and intuitive:

module "consul" { source = "github.com/hashicorp/consul/terraform/aws" servers = "5" }

resource "aws_instance" "bar" { ...

user_data = "${module.consul.server_address}" }

Terraform has built-in module management. It knows how to download modules from GitHub, BitBucket, Git, Mercurial, HTTP, and file paths. This makes distribution and management a first class feature of Terraform so external tooling will not be necessary.

And as you can see in the example above, you can pass in parameters to modules as well as read data back out.

When graphing modules, they are shown as a single unit:

But Terraform can also expand them for you:

Modules are fully documented here

Dynamic Resource Counts + Index Variable

Terraform has always supported a count meta-parameter to create multiple copies of a resource. Prior to 0.3, this count had to be static in the configuration, and you couldn't know within the resource what number you were in order to slightly change configurations. Both of these have been addressed in Terraform 0.3.

resource "aws_instance" "server" { ...

count = "${var.servers}"

tags { Name = "Server ${count.index}" } }

In the example above, the count is being dynamically set from the servers variable. And we're setting the "Name" tag to a name that includes the current count index. Both of these features are new.

By supporting dynamic counts, plus modules mentioned above, interesting things can be created such as dynamically scaling services. And with access to the index, issues with unique keys can be avoided.

User Experience: Init, Apply, User Input

We spent a lot of time with Terraform 0.3 improving the user experience surrounding Terraform. To this end, we've done a few major things.

First, we introduced the init command, which can initialize a directory with Terraform configurations from a module. So, for example, if you wanted to get started using the Consul module as a foundation, you could run the command below:

$ terraform init github.com/hashicorp/consul/terraform/aws ...

Next, we changed apply so that it can take a module URL. This is great for getting started with Terraform or showing off a demo. For example, if you just care about creating a Consul cluster quickly, you can run the command below and have an arbitrarily sized Consul cluster up and running in one command. Imagine doing this for any software on any underlying infrastructure provider.

$ terraform apply github.com/hashicorp/consul/terraform/aws ...

And finally, we introduced user input. Terraform will now interactively ask for input for provider configurations and variables. You can see that by running the command above, or by viewing the screenshot below.

And so much more...

Terraform state files are now JSON, instead of a binary format. This improves readability and lets users modify the state files in the case of mistakes or bugs. We don't think this will be a common thing but it is nice to know that it can be done.

Provisioner output is now visible. Before, output from provisioners was only shown in logs. This output is now streamed to the console. This greatly helps debuggability if servers aren't coming up properly.

Create before destroy mode. You can now specify that a resource has "create before destroy" enabled. This means that if you make a change that requires the resource to be destroyed, Terraform will first create the new resource before destroying the old. Note that this doesn't work for all resource types, but you now have the option to enable it.

Configuration format improvements. Trailing commas on final list elements are now valid, escaping double-quotes is fixed, and a few other minor issues.


Terraform 0.3 is a massive release. It brings not only a large number of features but also a lot of stability to the project. As we said earlier, this is the release to try if you've been waiting to jump onto Terraform.

We already have branches active adding some great features to Terraform 0.4, the next release. We also have some minor features coming into 0.3.1 and onwards. A top priority in the short term will be an OpenStack provider, which has been very heavily requested.

The future is bright for Terraform, and we're seeing a lot of folks having great success with the tool. Go download it and give it a try!