Overview
Terraform is an open-source infrastructure-as-code (IaC) tool created by HashiCorp written in Go. The tool helps to codify the infrastructure lifecycle (e.g. provision, update, destroy) in a human-readable format. It supports multiple cloud platforms.
Terraform takes a declarative approach to IaC. Users declare the end state of the resource in HCL; the tool will provision/update the resource accordingly, converging to the declared state. An alternative approach is imperative, which works by sequentially executing the instruction set from users.
In layman’s terms, the declarative approach focuses on the WHAT and the imperative approach focuses on the HOW.
In the rest of the article, we will go through a quick example of managing an AWS EC2 instance with Terraform, and see how the declarative design comes into play.
Getting Started
Suppose the Terraform CLI is installed (if not, go here).
Let’s spin up a free-tier eligible Amazon Linux instance in us-east-2
.
First, find the AMI (Amazon Machine Image) and instance type:
Next, make a directory and create a terraform configuration file main.tf
with the following:
terraform {
// specifies what provider plugins to download
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.27"
}
}
required_version = ">= 0.14.9"
}
provider "aws" {
profile = "default"
region = "us-east-2"
}
resource "aws_instance" "test_amazon_linux_freetier" {
// previously found ami and instance type
ami = "ami-002068ed284fb165b"
instance_type = "t2.micro"
tags = {
Name = "FreeTierAmazonLinux"
}
}
Let’s initiate terraform in this directory with terraform init
.
To validate the configuration, we can run terraform validate
.
To view the changes to infra, we can run terraform plan
. This is useful in reviewing planned changes to accept/reject them before carrying out the plan.
Time for the plan to come true! Run terraform apply
.
Everything looks good!
What happens if we manually modify the resource?
Let’s try manually editing the instance name on the console from FreeTierAmazonLinux to RandomName.
What’s going to happen if we run terraform apply
now?
Will it provision a new EC2 instance? (Hint: Nope)
Recall that terraform is declarative - the config file declares the end state of the resource. Now that the actual instance config has changed due to the manual editing, if we run terraform apply
again, terraform should compare the actual infrastructure state with the declared state (tracked in terraform.tfstate
file), detect the differences in instance name, and modify it back.
Let’s see it in action:
As expected, terraform picked up the state differences. Once the plan is accepted by the user, it changes the resource name back to FreeTierAmazonLinux.
Destroying the Resource
Destroying the resource couldn’t be easier - because the states are tracked, you can just run terraform destroy
in the current directory. Terraform will look at the state and figure out what to destroy.
Now, what if we delete the resource manually before running terraform destroy
? Will it cause a conflict of some sort?
Your guess is as good as mine but let’s mess it up together.
Nothing’s messed up. Terraform detected that the resource was modified outside of terraform and there is nothing to destroy. It simply updated the terraform.tfstate
to mark this state update.
Final Words
Hope you enjoy the read! This was a terraform 101 session for me as well. If you have any feedback about the content, please feel free to open an issue/PR under this blog’s repo.