Terraforming your infrastructure

Frank Klaassen

21 juni 2018

This blogpost is an introduction to Terraform, a tool to “shape your infrastructure” using code.

What is Terraform?

Terraform is an opensource tool developed by Hashicorp, which is probably best known for Vagrant and Consul.

It allows you to write out your infrastructure plan in code and have it actually setup the environment as you envisioned in one of the major cloud providers such as AWS, Google Cloud or Azure but also on your own VMWare vSphere environment.

Terraform Write Plan Create

Why should I use Terraform?

Terraform has a lot of advantages over manually setting up and configuring the environment.

Speed

A big win here is the fact that setting up the actual environment will only take you a few minutes after you wrote the Terraform configuration for it.

Initially it may take some time to get things working as desired, but once you have this it can be simply reused for future setups.

When we setup a new environment at a cloud provider a few things have to happen:

  1. The account has to be created, billing etc configured
  2. Network-related features (like VPN- and/or peering connections, security groups, routing tables etc) have to be configured
  3. Security-related features like firewalls and security groups have to be setup
  4. Instances have to be created and installed
  5. Every component (e.g. instance, volumes, network interfaces) has to be tagged for billing/analytics purposes.

Before Terraform, setting this up took was quite time consuming.
To add to that, because of the various components that needed to be configured manually sometimes things were forgotten (e.g. forgetting to set a particular tag).

Collaboration

In the past, setting up an environment was usually a one-man task. This person would have the most knowledge over the infrastructure that needed to be setup and/or cloud provider used and would take care of this.

However, this also adds risk. What if they get sick, go backpacking in Thailand for 4 weeks or go on maternity leave? Sure, a lot is documented but this is also a manual task.

The Terraform configuration can be placed into a repository (e.g. git), which adds a few additional advantages:

  1. Configuring can become a team-task rather than a one-person task
  2. The complete history of your infrastructure versions can be tracked, you can easily see what has changed between versions and who made the change.
  3. The code is basically self-documenting, no need to explain what is being done since it can be read from the code
  4. You can apply all kinds of checks and automations to ensure the changes done are correct or even apply them automatically

Code in Terraform can be turned into modules, which can be re-used for future usage or across teams and organizations.

Building reproducible infrastructures

Your Terraform plan serves as a blueprint for your infrastructure. As long as the blueprint stays the same (and the infrastructure itself as well) everything remains the same.

But making changes to your plan is easy and safe, because you can see which changes it would apply before actually applying them. This reduces mistakes and uncertainty.

Having your infrastructure blueprinted makes it easy to clone and migrate to other environments. With it, you can easily setup identical staging, QA or production environments.

If you like, you can even have multi-cloud deployments configured in one plan. Do you want an environment at both AWS and Google Cloud? No problem!

Integrations

Terraform offers a lot of integrations out-of-the-box. Apart from integrations with the major cloud providers it can also integrate with other software or SaaS services like Consul, CloudFlare, LetsEncrypt, Jira, NewRelic, Zabbix or provisioning tools like Chef, Puppet or Saltstack. But this is only a small selection of what is possible.

On top of that, you can extend Terraform yourself a well by writing custom plugins or using one of the community plugins.

How does it work?

Imagine you want to setup a small environment with a loadbalancer and 5 webserver EC2 instances on AWS. With the following Terraform plan you can set this up in matter of seconds, rather than minutes.

resource "aws_elb" "frontend" {
  name = "frontend-load-balancer"
  listener {
    instance_port     = 8000
    instance_protocol = "http"
    lb_port           = 80
    lb_protocol       = "http"
  }
 
  instances = ["${aws_instance.app.*.id}"]
}
 
resource "aws_instance" "app" {
  count = 5
 
  ami           = "ami-477b773e"
  instance_type = "t2.micro"
}

What this does:

  1. It creates 5 identical EC2 instances of type t2.micro with Ubuntu 18.04 LTS
  2. It creates an Elastic Loadbalancer (ELB) which listens on port 80 and links all of the instance we just created to this loadbalancer

If we then pass this to the plan feature of Terraform it will tell us what it will do

terraform plan
Terraform shows what it will do once we apply it

If we then tell it to apply, we get a final summary of what Terraform will do for us and a decision whether we are sure about it.

terraform apply - confirmation
If we are sure, Terraform will do its work

This is just a (very) basic example. It can however be fully customized and expanded to include specific instance configurations (e.g. larger disks), database instances, S3 buckets etc or even have the machines automatically provisioned using your tool of choice.
With this you can make very scalable and resilient infrastructures.

In the example above it looks like it will create the loadbalancer before the instances due to the ordering. However, Terraform will automatically detect any dependencies and adjust its order to create a situation that is possible.

The sky is the limit really. I hope this blog inspired you to take a look at this wonderful tool which should be a part of your DevOps arsenal.

If you are looking for a technical partner to take care of this for you, we may be able to help you out through our Support, Hosting & Infrastructure services.