Infrastructure as Code (IaC) and Terraform

Posted on April 21, 2022 by Adrian Wyssmann ‐ 5 min read

While I am am huge fan of Ansible not everything can be done out of the box. My issue particularly is the configuration of Cloudflare, which I still do via the Web UI.

Terraform vs. Ansible

Readers of my blog, know that I am not only a huge fan of Ansible as well as of Cloudflare. However there is currently only an Ansible module to configure Cloudflare DNS, but not everything there is 🤔. This is where Terraform comes in, as it offers a provider for cloudflare

As an Ansible user, the principal question is where Ansible differs from Terraform. Well the answer is right here

Configuration management tools install and manage software on a machine that already exists. Terraform is not a configuration management tool, and it allows existing tooling to focus on their strengths: bootstrapping and initializing resources.

Terraform focuses on the higher-level abstraction of the datacenter and associated services, while allowing you to use configuration management tools on individual systems. It also aims to bring the same benefits of codification of your system configuration to infrastructure management.

If you are using traditional configuration management within your compute instances, you can use Terraform to configure bootstrapping software like cloud-init to activate your configuration management software on first system boot

So while Ansible has it’s purpose, it seems Terraform is a better fit for setting up infrastructure from scratch?

Terraform and Infrastructure as Code (IaC)

Terraform is a tool for infrastructure as code, or as they state

Terraform codifies cloud APIs into declarative configuration files.

So what does that mean? Traditionally infrastructure is managed and provisioned manually, where an operator logs in into a management portal and the performs some actions - clicking in a user guide. Perhaps based on a ticked from a customer, which instructs him, what is needed. This works fine if you have only few elements and tickets to deal with. As soon as your infrastructure gets bigger, that will become challenging. Today, in the cloud area, which is mostly API driven, this offers new opportunities. Having APIs, Having APIs, means you can write scripts, which translates the work of the operator into executable code, that can be stored in source control. this makes changes more robust and prone to human errors, as well as changes can be tracked and versioned, so you can go back to an earlier configuration in case of failures. Ultimately you have a tool like Terraform, which eliminates the needs for scripts, as the tools implements the logic of talking to the APIs. Hence you can describe your infrastructure, in a more human readable manner, often called configuration files.

Terraform uses its own Configuration Language, so that a user can declare [resources]. It also implements features, which makes the definition of resources more flexible and convenient, for example by the use of variable.

Such a language construct looks like this:

<BLOCK TYPE> "<BLOCK LABEL>" "<BLOCK LABEL>" {
  # Block body
  <IDENTIFIER> = <EXPRESSION> # Argument
}
  • Blocks are containers which define an object, whereas a blco
    • has a type block
    • has zero or more labels
    • has a body that contains any number of arguments and nested blocks
  • Arguments assign a value to a name
  • Expressions represent a value, either literally or by referencing and combining other values.

Terraform concept

Terraform uses so called providers to interact with cloud providers, SaaS providers, and other APIs

terraform concept

You can find providers in the Terraform Registry, where you can find official providers, as well as providers written by the community - see also How to Find Providers.

Each provider adds a set of resource types and/or data sources that Terraform can manage.

  • resources: Each resource block describes one or more infrastructure objects, such as virtual networks, compute instances, or higher-level components such as DNS records.
  • data sources: Use information defined outside of Terraform, defined by another separate Terraform configuration, or modified by functions.

Terraform Workflow

The core Terraform workflow consists of three stages:

  • Write: In this stage you define the resources and write them using TF Configuration Language
  • Plan: This is where you tell Terraform to create an execution plan. The plan describes the infrastructure it will create, update, or destroy based on the current state (see below)
  • Apply: If you approve the plan, Terraform will perform the proposed operations in the correct order, respecting any resource dependencies, as verified in the plan
terraform workflow

The workflow shows some important elements for Terraform:

  • state: Is the information about the managed infrastructure and configuration incl. metadata (e.g. resource dependencies). This is stored in the backend which by default is a file terraform.tfstate on the local file system. state purpose explains why the state is needed:

    • it maps Terraform config to the real world, so that each remote object is bound to only one resource instance
    • track metadata like dependencies, so that Terraform knows when to update or even delete objects
    • cache the attribute values for all resources, so that changes to the configuration can effectively determined
    • synch and lock the state so that multiple people can work with the configuration, but avoiding two or more different users accidentally running Terraform at the same time
  • backends: Backends define where Terraform’s state snapshots are stored - by default this is local i.e. local file on disk. A bunch of backends is already built-in, while additional backends can be loaded as plugins.

    terraform {
       backend "remote" {
          organization = "wyssmann_org"
    
          workspaces {
          name = "my-app-prod"
          }
       }
    }

To interact with Terraform you usually use the Terraform CLI. I won’t go into details of this post, but we will see more in subsequent posts.

What comes next?

As this post only gives an intro what Terraform is, and how it generally works, in upcoming posts I will work with concrete examples.