|7 min read

Terraform: The IaC Tool I Have Been Waiting For

HashiCorp just released Terraform and it fills the infrastructure-as-code gap that has been bothering me for months

HashiCorp released Terraform 0.1 two days ago, and I have been playing with it nonstop. I know I say this about a lot of tools, but this one genuinely fills a gap that has been bothering me for a long time.

Let me explain what that gap is and why Terraform matters.

The Gap

We have configuration management tools like Ansible, Chef, and Puppet. They are great at configuring servers: installing packages, managing files, starting services. But they are designed for managing the inside of servers, not for creating the servers themselves.

When I need to provision infrastructure, to create a VM in VMware, launch an instance in AWS, set up a load balancer, configure a VPC, create DNS records, I have been using a patchwork of approaches. Shell scripts that call APIs. Manual console work. Cloud provider CLIs. Custom tools that wrap cloud provider SDKs.

None of these approaches give me what I really want: a declarative, version-controlled, reproducible way to define my entire infrastructure stack.

Ansible can create AWS resources using its cloud modules, but it was not designed for this purpose. The cloud modules feel bolted on. Chef has a provisioning framework, but it is complex and heavyweight. CloudFormation works for AWS but only for AWS, and the JSON templates are verbose to the point of being painful to write and impossible to read.

Terraform is designed from the ground up for exactly this problem. It is an infrastructure-as-code tool that lets you define, provision, and manage infrastructure across multiple providers using a single, consistent workflow.

The HCL Syntax

Terraform uses a custom configuration language called HCL (HashiCorp Configuration Language). It sits somewhere between JSON and a full programming language, and it hits a sweet spot that I find really appealing.

Here is what a simple AWS instance definition looks like:

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  tags {
    Name = "web-server"
  }
}

Compare that to the equivalent CloudFormation JSON:

{
  "Resources": {
    "WebServer": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "ImageId": "ami-0c55b159cbfafe1f0",
        "InstanceType": "t2.micro",
        "Tags": [
          {
            "Key": "Name",
            "Value": "web-server"
          }
        ]
      }
    }
  }
}

The HCL version is more readable, more concise, and easier to write. It supports comments (JSON does not). It supports variables and interpolation. It supports modules for reusability. It is human-friendly in a way that CloudFormation is not.

The Plan and Apply Workflow

This is, in my opinion, Terraform's killer feature.

When you run terraform plan, it compares your desired state (defined in your .tf files) with the current state of your infrastructure and shows you exactly what it will create, modify, or destroy. Nothing happens yet. You are just looking at the plan.

When you are satisfied that the plan looks correct, you run terraform apply and Terraform makes the changes.

This two-step workflow is brilliant for several reasons.

First, it prevents surprises. Before making any change to your infrastructure, you see exactly what will happen. No "oops, I accidentally terminated the production database" moments.

Second, it enables code review. You can commit your Terraform changes to version control, have someone review the plan output, and approve the change before it is applied. Infrastructure changes go through the same review process as application code changes.

Third, it makes infrastructure changes auditable. Every change is tracked in version control. You can see who changed what, when, and why. You can revert to a previous state by reverting to a previous commit.

Multi-Provider Support

This is the other big differentiator. Terraform is not tied to a single cloud provider. It has a provider plugin architecture that supports AWS, Google Cloud, Azure, VMware, OpenStack, DigitalOcean, and many others.

This means you can define your entire infrastructure, across multiple providers, in a single Terraform configuration. Your AWS instances, your DNS records in Route53, your monitoring in Datadog, your PagerDuty alerts, all defined in the same files, managed by the same tool.

For someone like me who manages infrastructure across VMware on-premises and is starting to use AWS, this multi-provider approach is incredibly valuable. I do not want to learn one tool for VMware and a different tool for AWS. I want one tool that speaks both.

State Management

Terraform maintains a state file that maps your configuration to real-world resources. When you create an AWS instance through Terraform, the state file records the instance ID, its IP address, and all its attributes. When you run terraform plan again, Terraform reads the state file and compares it with the actual state of the resource in AWS.

This state management is what enables Terraform to know what changes need to be made. Without it, Terraform would have no way to know if a resource already exists or needs to be created.

The state file is also what makes Terraform different from a simple script that calls APIs. A script creates resources but does not track them. If you run the script twice, you get duplicate resources. Terraform's state tracking prevents that.

The state file does introduce some challenges. It needs to be stored securely (it can contain sensitive data like passwords and API keys). It needs to be shared if multiple people are working on the same infrastructure. And it needs to be kept in sync with reality (if someone makes a manual change outside of Terraform, the state file becomes inaccurate).

These are solvable problems, but they are worth being aware of.

How I Am Going to Use It

I have a few immediate use cases in mind.

Lab environments: I frequently need to spin up multi-server lab environments for testing. Right now, I do this manually through the VMware console. With Terraform's VMware provider, I could define a lab environment as code and create or destroy it with a single command.

AWS infrastructure: We are starting to use AWS for some workloads. Rather than clicking through the AWS console (which is how we have been doing it, and I am embarrassed to admit it), I want to define our AWS infrastructure in Terraform from day one. VPCs, subnets, security groups, instances, all in code.

Documentation through code: One of the persistent challenges in our team is knowing what infrastructure exists and how it is configured. Terraform configurations serve as living documentation. If you want to know what our AWS environment looks like, you read the Terraform files.

The HashiCorp Ecosystem

Terraform is part of a broader set of tools from HashiCorp, and they fit together nicely. Vagrant for development environments. Packer for building machine images. Consul for service discovery. Terraform for provisioning infrastructure.

Mitchell Hashimoto and the HashiCorp team clearly have a coherent vision for the infrastructure toolchain. Each tool addresses a specific part of the infrastructure lifecycle, and they integrate well with each other. Packer builds an AMI, Terraform provisions an instance using that AMI, Consul provides service discovery for the running instance.

I have been using Vagrant for a while now and I am impressed with how HashiCorp builds tools. They focus on developer experience, they design clear abstractions, and they build for the real-world workflow rather than some idealized version of it.

Early Days, Big Potential

Terraform is at version 0.1. The provider ecosystem is limited. Some features are rough. Documentation for advanced use cases is thin. I have hit a few bugs in my testing.

But the foundation is solid. The architecture is sound. The workflow is right. And the problem it solves is real and important.

I have a strong feeling that Terraform, or something very much like it, will become a fundamental part of every infrastructure team's toolkit. The idea of defining infrastructure in code, planning changes before applying them, and managing state across multiple providers is too compelling to ignore.

For now, I am going to keep experimenting, keep learning, and start using Terraform for non-production infrastructure. By the time it reaches 1.0, I want to be ready to use it for everything.

Share: