Terraform your Infrastructure!

What is Terraform and why do you need it?

If you have any resources in AWS/Google Cloud/Azure, etc. its a high likelihood that terraform can improve your workflow and make management of your cloud resources a breeze! I have used it with AWS, so, most of this post will discuss terraform in context of AWS. But, it works fine with Google Cloud, Azure, Alibaba cloud, etc.

What is Terraform?

Terraform (https://www.terraform.io/) is an open source project by Hashicorp written in golang (https://golang.org/). It lets you define cloud resources (servers, s3 buckets, lambda functions, IAM policies, etc.) in code and check them into a source control. You can then “execute” the configuration and create/modify/delete all the cloud resources with a single command.

On a mac, terraform can be installed using brew brew install terraform

Using Terraform:

  • terraform init : Creates a .terraform directory
  • terraform plan : Outputs how terraform interprets the main.tf file and what resources it will create/modify/delete. Its a dry-run. Which is very critical because you would like know exactly what changes it will do your cloud resources. Surprises are bad!
  • terraform apply : Reads the main.tf and makes all the changes to the cloud. This step outputs a .tfstate file that contains identifiers of cloud resources. This generated file is very important and you should never edit this manually.

A best practice is to set up a terraform role in IAM on AWS, use that to manage resource access to terraform and then execute it on the machine with that role. It is also recommended to keep a copy of .tfstate file in a separate folder. Terraform keeps a backup of this, but just in case something goes wrong, you would want to keep that handy. If .tfstate goes missing or gets changed, terraform will not be able to update/delete affected resources.

Sample tf file to create s3 bucket

  provider "aws" {
    region = "<region>"
  }

  ##################################################################
  # S3 bucket config
  ##################################################################

  resource "aws_s3_bucket" "code_bucket" {
    bucket = "<bucket name>"
    acl    = "<ACL>"

    tags {
      <tag1 name>        = "<tag1 value>"
      <tag2 name>        = "<tag2 value>"
    }
  }

You can see here, its pretty straightforward to move accounts, create and recreate similar buckets and manage them using flat files. You can commit them and version in git, and get all the nice things like branching, tagging, reverting to an older stable version in case of a bad change, etc.

Reusing configuration: Terrafom Modules

Terraform also has a modules registry (https://registry.terraform.io/) where you can find pre-built modules and get started pretty fast. You can also build internal modules in your organization and re-use or distribute them. Without terraform, recreating the whole set up becomes time-consuming and error-prone.

Alternatives

AWS Cloudformation also provides similar features to terraform. But, there are some pros and cons to each. Major one being Cloudformation only works with AWS whereas Terraform works with a lot of providers. I have also found it easier to manage configuration and user data scripts on Terraform compared to Cloudformation. On the other hand, Terraform lags a bit behind on new features on AWS compared to Cloudformation.

Eventually, to pick between Terraform and Cloudformation, it is a matter of deciding what the project needs in terms of priorities and requirements.