Getty Images/iStockphoto

Tip

Terraform cheat sheet: Notable commands, HCL and more

Terraform has a lot going on. This cheat sheet rounds up the essentials, from configuration settings to the key commands for managing the Terraform directory.

Terraform is one of the most popular system configuration and deployment platforms for describing infrastructure as code. Much like a program or script encodes computer instructions, Terraform encapsulates the parameters necessary to deploy virtual infrastructure on a public cloud service or private data center via a service's management APIs.

As a cloud-agnostic and open source tool, Terraform runs on any PC, server or cloud instance. Terraform can create infrastructure on popular cloud platforms including AWS, Microsoft Azure, Google Cloud Platform, IBM Cloud, Oracle Cloud, OpenStack and VMware.

Unlike infrastructure as code (IaC) tools that support conventional scripting languages like Go, JavaScript, Python or TypeScript, Terraform uses the HashiCorp Configuration Language (HCL), an easy-to-read domain-specific language created by Terraform's developers. The HCL specification is compatible with a JavaScript Object Notation (JSON) variant suitable for machine program generation and parsing. According to HCL's developers, the language draws inspiration from libucl -- the universal configuration library parser -- Nginx and similar configuration languages. And JSON support significantly improves interoperability.

Read on for a deeper explanation of how it works, and find a quick Terraform cheat sheet of key commands you need to know.

Syntax

HCL syntax is basic and should be readable by those familiar with other scripting languages. It has three core elements: blocks, arguments and expressions.

  1. Blocks group expressions, arguments and other blocks into a labelable structure, which external blocks can then reference. Its curly bracket syntax is shared by most object-oriented languages.
  2. Arguments are an abstraction that enable IT admins to assign values to descriptive names, which can represent the value within expressions.
  3. Expressions either represent or compute values. They can be simple, such as a string or numeric value, or more complicated, such as arithmetic or logical expressions.

The following code illustrates the basic structure of blocks and a simple example that configures a virtual private cloud (VPC) network range.

<BLOCK TYPE> "<BLOCK LABEL>" "<BLOCK LABEL>" {
  # Block body
  <IDENTIFIER> = <EXPRESSION> # Argument
}

variable "base_cidr_block" {
  description = "A /16 CIDR range definition, such as 10.1.0.0/16, that the VPC will use"
  default = "10.1.0.0/16"
}

resource "aws_vpc" "main" {
  cidr_block = var.base_cidr_block
}

Variables, outputs and functions

Terraform variables and outputs are blocks that require parameters (input variables) or generate data (output values), and are used to create functions. Like other programming or scripting languages, Terraform has many built-in functions for common expressions. Examples of how these functions are grouped include the following:

  • numeric (min, max, log, etc.);
  • string (split, join, replace, etc.);
  • encoding (base64encode-decode, base64gzip, etc.);
  • date and time;
  • hash and crypto (bcrypt, md5, sha256, etc.); and
  • IP network (cidrsubnet, cidrnetmask, etc.).

Resources and blocks

Resources are the declarative descriptions of infrastructure objects in HCL. They are comprised of many attributes, which are named and wrapped in a block. Each infrastructure provider -- for example, AWS, Azure and OpenShift -- has a list of available resource categories and types that are used in module definitions.

For example, the Terraform AWS provider has categories for each AWS service; the VPC category, which we will use in the following example, has over 40 resource types. The following code defines a VPC network block and subnet on a single availability zone, us-west-2a.

resource "aws_vpc" "my_vpc" {
  cidr_block = "172.16.0.0/16"

  tags = {
    Name = "tf-example"
  }
}

resource "aws_subnet" "my_subnet" {
  vpc_id            = aws_vpc.my_vpc.id
  cidr_block        = "172.16.10.0/24"
  availability_zone = "us-west-2a"

  tags = {
    Name = "tf-example"
  }
}

Files and modules

Terraform configurations tell the system how to provision and manage infrastructure, whether that is an individual compute instance or a complete server, container, storage and network environment.

A configuration can consist of multiple files and directories. By convention, Terraform files are named with a .if or .json suffix.

A module is a collection of files, typically kept in the same directory, that groups similar resources together and reuses common resource configurations.

State

Terraform stores the state of resource configurations automatically in a separate terraform.tfstate file that can be local or, preferably, on a centralized management system. State and metadata map resources to the source configuration, track dependencies and cache resource attributes to improve performance when searching for instances or types across a resource fleet.

State files are written in JSON and managed via the Terraform state command, which takes one of two subcommands, list or show. To synchronize the state with the resources currently deployed, use the refresh command.

The state list command returns all resources in the state file, or those that match the specified addresses. For example:

terraform state list aws_instance.testapp

aws_instance.testapp[0]
aws_instance.testapp[1]

The state show command displays the attributes of a single resource. For example:

terraform state show aws_instance.ec2testapp 
# shows details about EC2 instance such as
region = us-west-1
ami = ami-20210504
instance_type = m5.large
etc.

The commands terraform refresh and terraform apply -refresh-only process the managed remote objects set for the environment and update the state accordingly. However, the latter, and safer, option provides an interactive prompt to approve each detected change.

Terraform workspaces separate state data from multiple instances using resources configured from the same working directory.

Working with Terraform

Like every programming environment, Terraform organizes files in a working directory. Save the following Terraform cheat sheet to keep at hand to create and manage this directory smoothly:

  • terraform init. Prepares a working directory that holds a configuration or checks out a working directory from a version control system, when used with the option -from-module:MODULE-SOURCE.
  • terraform get [options] PATH. Downloads and updates modules defined in the root module.
  • terraform workspace. Depending on the specific workspace command -- list, select, new, delete or show -- this lists available workspaces, chooses a particular option, creates a workspace, deletes a selected workspace or displays the current one.
  • terraform plan. Creates an execution workflow, also called a plan. When this command runs, it reads the state of remote objects with terraform refresh, identifies the differences between the prior and desired states and lists a set of changes that will synchronize the remote objects with the desired configuration.
  • terraform apply. Executes the actions created from a Terraform plan.
  • terraform validate. Checks code syntax and whether a configuration is internally consistent.
  • terraform fmt. Reformats configuration files to a standard style using a subset of the Terraform Style Conventions. These style conventions specify, for example, to use a two-space indentation for each nesting level and to separate logical groups of arguments by an empty line.
  • terraform graph. Generates a visual depiction of a configuration or execution plan using the GraphViz DOT format. This visual can be converted to an image using GraphViz's dot command. For example, the following command and Figure 1 illustrate the plan for an AWS environment with three EC2 instances front-ended by AWS Elastic Load Balancing and using Route53 for DNS.
terraform graph | dot -Tpng > terra-graph.png
Terraform graph command returns a configuration or execution plan visual
Figure 1

Next Steps

Use Kubernetes and Terraform together for cluster management

How to launch an EC2 instance using Terraform

Simplify code with for_each and dynamic blocks in Terraform

Deploy an app on Google Cloud Run with Terraform

Set up a Terraform S3 backend with this video tutorial

Dig Deeper on Systems automation and orchestration