The busy developer’s guide to Terraform

TLDR:  Terraform is a tool to manage your infrastructure as code.  You define configuration files that describe your infrastructure.  Terraform generates an incremental plan to apply any changes.  After you review the plan, Terraform will then apply it to update your infrastructure.

Why use Terraform?

Terraform allows you to define your infrastructure as code.  Terraform has support for many existing cloud providers.  Tools like Chef, Puppet, Ansible, and SaltStack are all configuration management tools. These tools come after provisioning the hardware.

Terraform allows your infrastructure to be:

  • Version controlled – now you have a historical log of all infrastructure changes.
  • Shareable – easily view and share the current state of your infrastructure.
  • Self-serving – any engineer can view and make a PR to provision infrastructure resources.
  • Easily deployed – Terraform plans the incremental changes needed. Then applies those changes so that your infrastructure state matches your defined configuration.

What is Terraform?

Terraform is an open-source tool created by Hashicorp.  Terraform allows you to declare your desired infrastructure as Terraform configuration files (.tf).  Then Terraform will plan the changes needed to match your given configuration with the infrastructure on your cloud provider. 

It is a declarative tool, like Kubernetes.  You declare the end state, Terraform makes it happen.

Terraform Process

  1. Specify your cloud provider in one of your Terraform configuration files.
  2. Define your resources in Terraform configuration files.  These configs are the “code” part of ‘infrastructure as code’.
  3. Execute a `terraform apply` and Terraform will make API calls to your cloud provider. These calls will update your infrastructure per the configurations you’ve declared.

How to use Terraform?

Terraform uses HashiCorp Config Language (HCL).  This basic overview will help you understand what it is your looking at when you come across .tf files in the wild.

The purpose of your Terraform configuration is to declare resourcesResources are the actual infrastructure objects to be provisioned.  All other elements of the configuration language exist to help you define resources.

Configuration Language Overview

Terraform Blocks

Terraform will read all .tf files in it’s working directory.  These files are collections of blocks.  A block is just a container for more specific configuration content.

In HCL, blocks have a certain block type.  These block types specify the syntax of what the rest of the block needs to look like.  The general block structure is this:

  # Block body

Every block starts with a block type.  This defines how many labels a block needs.  The content of the block is inside the { }.

Terraform Resources

The most important block type is “resource”.  A resource type requires two block labels – the resource type to provision and the local name to label this resource.  For example:

resource "aws_instance" "my_app" {
  ami           = "ami-abc123"
  instance_type = "t2.micro"

In the example above, “aws instance” is the resource type to provision in AWS. While “my_app” is the resource name, which could be any value.  The name can be used inside the same Terraform module to refer to this resource.  Inside a module, the combination of the resource type and resource name must be unique.

View the Resource Documentation to see all resource types available in Terraform.

Terraform Expressions

 Expressions are how values inside a block are defined.  Most are the typical types and values you might expect, view the full list here.

To reference named values use “<resource type>.<name>”.  This represents a resource object you’ve created.

If you’ve defined variable or data objects then use  “var.<name>” or” data.<data type>.<data name>” respectively.

Terraform also has several built-in functions.

Terraform Variables

Variables are a block type that can be defined in Terraform.  By convention, they are sometimes all located in a “” file.  All .tf files in your working directory are loaded by Terraform. You will have access to all variable resources defined in your working directory.

To access the value in a variable use “var.<variable name>”.

Terraform Modules

A module in Terraform is an abstraction layer.  Use modules to combine multiple resources that are used together into a single block.

Modules also make it easy to share and re-use parts of your Terraform code elsewhere.  

At a minimum, all projects have the Root module by default.  Any other modules will be declared as a module block type.

Terraform Providers

The provider block type is how you tell Terraform which API to call to provision your resources.  It’s also how you specify the credentials to your cloud provider.

Here’s a full list of providers supported by Terraform.

Next Steps with Terraform

Pick your cloud provider and follow the getting started guide to install Terraform.

Additional Reading