What Is Terraform and How Does It Work

What is Terraform?

Terraform is a convergence-based, push-model "infrastructure as code" (IaC) tool that uses a declarative programming language (HCL) to describe the desired state of the infrastructure. The systems that Terraform manages are in general mutable, meaning that you manage their configuration over their entire lifecycle instead of rebuilding them from scratch on every configuration change, like you'd do with Docker containers, for example.

All these terms are explained in our Understanding infrastructure as code article which is highly recommended if don't already have a moderate amount of IaC experience.

Astronaut sitting in desert ground with a laptop

How does Terraform work?

Terraform uses HCL code to determine the desired state of the infrastructure. When Terraform creates a new resource it adds its details (type, unique identifier, parameters) to a record called Terraform state file. A resource can be a cloud VM, a virtual routing table, a database user, or something else.

The Terraform state file is essentially a translation table between resources defined in HCL code and the actual resources stored in the system managed by Terraform.

When Terraform runs it

  1. Reads the HCL code to determine the desired state of the infrastructure
  2. Checks the state file to figure out the identifiers of the resources it is managing
  3. Checks if there are differences between reality and the desired state
  4. Does with takes to bring reality in line with the desired state (see convergence)
This process is shown in this diagram:

Terraform uses providers (plugins) to query and modify resources. The provider's responsibility is to translate HCL code into commands understood by the system Terraform manages. Most providers rely on API calls to do queries and modifications.

Terraform uses the push model to make changes because it has little choice: most of the things it manages (e.g. public Cloud and SaaS services) are only accessible via APIs and installation of an agent that could pull configurations is impossible.

What can Terraform manage?

Pretty much anything that has API can be managed by Terraform, for example:

  • Public Clouds (AWS, Azure, Hetzner, Digital Ocean)
  • Private Clouds (Openstack, oVirt)
  • Virtualization systems (vCenter, Hyper-V, KVM, Virtualbox)
  • Hardware devices (JuniperOS, FortiOS, Cisco)
  • Local applications (Keycloak, FreeIPA, MySQL, Kubernetes)
  • SaaS services (Slack, GitHub)
  • DNS (RFC2136, RFC2845, RFC3645, Cloudflare)

Most of the providers are available in the Terraform registry, but you can also find them from GitHub and elsewhere.

What Terraform can not manage?

Terraform is not suitable for managing the configuration of computer systems at the operating system level. For example, installation of applications, setting up configuration files and managing system services is outside its scope. For those tasks other configuration management tools like Puppet, Ansible or Chef are much more suitable. That said, this seemingly clear distinction is blurred by two things:

  • Terraform supports operating system level configurations in virtual machines via user_data (cloud-init) and with SSH and WinRM provisioners. That said, Terraform can only define the initial state of the system, not maintain it over its lifetime.
  • Terraform has many providers which can be used for configuring local applications such as MySQL, FreeIPA or GitLab.

What real-world problems does Terraform solve?

In the recent years IT infrastructure has become increasingly complex and fragmented. Organizations often have on-premise hardware, virtual machines in private or public Cloud, SaaS service subscriptions and maybe even containers running some workloads.

The core strength of Terraform is its ability to manage and glue together this diversity with its huge number of providers. This allows it to act as a bridge between Clouds, SaaS services, network devices and local applications. For example you can use Terraform to create a user to multiple places in one go, or to create a VM or a load balancer in one Cloud and then add a DNS record for it in another Cloud.