Author: Biswajit Kalita
This blog will help you learn yet another automation tool, especially with regard to cloud infrastructure - Terraform.
What is Terraform?
Terraform is an open-source infrastructure as a code software tool created by HashiCorp. It is a great tool for automating and managing your cloud infrastructure. Users define and provide data center infrastructure using a declarative configuration language.
If you don’t know what declarative language is:
Declarative = define what end result you want.
Meaning you don’t have to define each and every step of how this automation and management is done; you just have to tell what end result you want, and Terraform will figure out how to execute it.
On the other hand, we have Imperative languages like Java, where we define how to execute each step.
Installing Terraform on Windows:
Download the zip file from: https://www.terraform.io/downloads
Extract the zip file to obtain the executable file.
Add the location of this file to the system environment variable - path.
Run terraform -v in command prompt.
If you see the Terraform version as output, that means Terraform has been successfully installed. If you see anything else, then there is some issue in the installation.
Text editor - VS Code:
This is completely optional, and you can use any text editor of your choice. But I recommend using Visual Studio Code. It is a very powerful text editor tool provided by Microsoft, and it is free.
If you want to use it, you can get it from here: https://code.visualstudio.com/
After installing VS Code, also install the Terraform extension as shown below. It will provide a lot of features like auto-completion, auto-formatting, syntax highlighting, etc.

Terraform Overview:
1. Let’s create a folder where our Terraform files will get stored. Open up the folder in VS Code.
2. Create a file inside the folder and name it provider.tf. You can name it whatever you want, but the extension should be .tf
3. Now, the first thing we have to write in this file is to define a provider.
What is a Provider?
In Terraform, we have the concept of Providers. A provider is a plugin that allows us to talk to a set of APIs. For example, if you want to work with AWS then you need the AWS, provider.
If you go to https://registry.terraform.io/browse/providers , it will show you all the providers that Terraform supports.
If we define an AWS provider, then Terraform will download all the necessary codes required to talk to the AWS APIs. And we will be able to create and modify resources in our AWS account.
4. Write this code to define the AWS provider:
terraform {
required_version = "~> 0.13.4"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.70.0"
}
}
}
provider "aws" {
region = "us-west-2"
}
You can get the syntax from the Terraform docs: https://registry.terraform.io/providers/hashicorp/aws/latest/docs
The version is optional but recommended use. The region is the AWS region where Amazon has its data centers.
5. Authentication:
To authenticate, get the AWS Access key and Secret key from your AWS account. We can directly pass these keys in our provider configuration, but please DO NOT do this as it can lead to security issues when you push your code to git.
The best way to do this is by configuring AWS on your machine. Inside the .aws folder, you will have the credentials file. In this file, create a profile and provide the access key and secret key in it.

Then use the profile in the provider configuration as shown below.
provider "aws" {
region = "us-west-2"
profile = "dev"
}
6. Creating Resources:
Now let’s try to create an EC2 instance in AWS. For those who don’t know what an EC2 instance is - it is just a virtual machine inside AWS.
The syntax for creating a resource is like this:
Resource “<provider>_<resource_type>” “name” {
Config properties………
}
Here ‘name’ is the name we want to give to the resource so that we can refer to it within our code later. It will not be reflected anywhere in AWS.
So, our code will look like this:
resource "aws_instance" "my-first-ec2" {
ami =
instance_type = "t2.micro"
tags = {
Name = "HelloWorld"
}
}
Get the AMI id from AWS. AMI stands for Amazon Machine Image, which provides the information required to launch an instance.
Tags are optional. It is just a tag or a name for the ec2 instance, which will be displayed on AWS so that we can easily identify the instance that we have created.
7. Executing the Terraform:
Save the provider.tf file, which now looks like this:
terraform {
required_version = "~> 0.13.4"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.70.0"
}
}
}
provider "aws" {
region = "us-west-2"
profile = "dev"
}
resource "aws_instance" "my-first-ec2" {
ami =
instance_type = "t2.micro"
tags = {
Name = "HelloWorld"
}
}
If you are not using VS Code, then go to the location where this file is saved and open the command prompt there so that we can run the Terraform commands.
If you are using VS Code, then click on Terminal → New Terminal. It will open up a terminal and automatically take you to the root of your project directory. One other benefit of this is that we can see both our code and terminal at the same time.
The first command we need to run is Terraform init. When we run this command, Terraform will go through all the Terraform files we have, and it will look for all the providers we have defined. Then it will download all the necessary plugins. It will create a .terraform folder in your project directory which will hold all the plugins.
If everything goes right, you should see the green output message - Terraform has been successfully initialized!

The next command we will run is Terraform plan. It is optional but very highly recommended. It will show all the changes that are going to take place. It will show what we are going to create, what we are going to modify, and what we are going to delete. It is like a dry run or a sanity check before we actually apply the changes.
It will also color-code the changes for us. For the resources it is going to create, you will see a green plus (+) sign; for the resources, it is going to delete, you will see a red minus (-) sign, and for the resources, it is going to modify you see will an orange tilde (~) sign.

You will see many fields as “known after apply”, which means these values will be known only after actually deploying the changes to AWS.
So the next command we will run is Terraform apply. This will deploy all the changes that were shown above. If everything goes right, you will see a green Apply complete message. It will also display the number of resources added, deleted, or modified.
Now we can go to AWS and see that the EC2 instance has been created.

If you go back to your Terraform project, you can see a terraform.tfstate file has been created. Terraform creates this file to store the current state of the resources. So when you make any changes to your code, it can detect the difference between the current state and the code. Now, if you hit Terraform apply, it will only deploy the changes rather than deploying everything again.
Few Other Commands:
1. Deleting a Resource:
Now, if you want to delete the ec2 instance, then you have to run Terraform destroy
2. Referencing a Resource:
Let’s say you are creating a VPC, and at the same time, you want to create a subnet within that VPC. To create the subnet, you need the vpc id. But since the VPC has not been created yet, you can’t get the vpc id from AWS. Here is one more advantage of Terraform. You can refer to the resource, even though it has not been created yet, in the following way.
resource "aws_vpc" "dev-vpc" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "subnet-dev1" {
vpc_id = aws_vpc.dev-vpc.id
cidr_block = "10.0.1.0/24"
}
3. Terraform State Commands:
Terraform state list - this command will list all the resources that have been created.
Terraform state show <resource> - this command will show all the details of the particular resource.
Example: terraform state show aws_vpc.dev-vpc
4. Target Resource:
Let’s say you want to delete a particular resource only and don’t want to touch the other resources. In this case, we have to use the target command.
terraform destroy -target <resource>
Example: terraform destroy -target aws_subnet.subnet-dev1
It can also be used for selectively creating resource(s).
5. Terraform Workspace:
terraform workspace list - to list all the workspaces
terraform workspace select dev - to select dev workspace
terraform workspace new stage - to create a new workspace with a name stage
Terraform Variables:
1. Defining a variable:
A variable can be defined in the following way. It takes three arguments, as shown below, and all three of them are optional.
variable "vpc_cidr_block" {
default = ""
description = ""
type = string
}
2. Referencing a variable:
A variable is referred using var.<variable_name>
resource "aws_vpc" "dev-vpc" {
cidr_block = var.vpc_cidr_block
}
3. Assigning a value to a variable:
If we don’t assign any value to a declared variable, and we run Terraform plan or Terraform apply, then Terraform will prompt the user to Enter a value during runtime.
Another way of assigning a value during runtime is while doing Terraform plan or Terraform apply.
terraform apply -var “vpc_cidr_block=10.0.0.0/16”
The best way to assign values to variables is by creating a separate file for it. Terraform automatically looks for a file named terraform.tfvars
But it is not always good to have all our variables in a single file. We might want to have separate files for different environments. In this case, we can tell Terraform to look for a specific file using the below command.
terraform plan -var-file 'dev.tfvars'
