Terraform is a tool that makes it easier to set up and manage computing resources, like websites and virtual machines. Instead of manually configuring each resource, Terraform allows you to write instructions that define how the resources should be arranged and managed.

For example, let's talk about it as a blueprint for building a house, but for computer resources. You can plan exactly what you want with a blueprint, and the workers will use that plan to build the house. Terraform works similarly by taking your instructions and using them to set up and manage your computing resources automatically.

So, Terraform simplifies building and organising your computing resources using instructions instead of doing everything by hand.

Pre-Requisite

  • AWS Cloud Account (We'll work within the boundaries of the Free Tier)

How Does it Work?

Terraform works by using a declarative approach to manage infrastructure. This means that, instead of specifying how to build the infrastructure step-by-step, Terraform describes the desired end state of the infrastructure and the resources needed to achieve it. The Terraform configuration files are written in the HashiCorp Configuration Language (HCL) and define the resources that Terraform should manage, along with the desired state of those resources.

Terraform maintains a state file that tracks the current state of the infrastructure and compares it to the desired state defined in the Terraform configuration files. When Terraform is run, it generates a plan to make necessary changes to align the infrastructure with the desired state. The plan is then applied to make the changes to the infrastructure, which can include creating new resources, updating existing resources, or deleting resources that are no longer needed.

Terraform uses a variety of plugins, known as providers, to interface with various infrastructure services and cloud providers, such as AWS, GCP, and Azure. The providers allow Terraform to manage the infrastructure resources defined in the configuration files and provide a common set of resource types, regardless of the underlying provider.

Overall, Terraform provides a unified and streamlined way to manage infrastructure using a declarative approach and a centralised state file to track and manage resources. It achieves this while using plugins to interface with various infrastructure services and cloud providers.

Installation

Installing Terraform is pretty simple if you have a package manager like Homebrew, which I'll use for this article.

Run the following commands to set up Terraform on your computer.

brew tap hashicorp/tap
brew install terraform

To check for a successful installation, simply write: terraform -v

Creating Infrastructure with Terraform

Components of a Terraform File (.tf)

A Terraform configuration file consists of several components that define the infrastructure to be managed:

  1. Provider: The provider block defines the cloud or service provider Terraform will use to manage the infrastructure resources.
  2. Resource: The resource block defines the infrastructure resources that Terraform should manage, such as a virtual machine, a network, or a storage bucket. Each resource block specifies the type of resource to be created, the configuration options, and the desired state.
  3. Variable: The variable block allows you to define variables that can be used in Terraform configuration files. This makes it easier to reuse code and manage configuration options centrally.
  4. Data: The data block allows Terraform to retrieve data from an external source, such as an API or a file, and use that data in Terraform configuration files. This can be useful for retrieving information about existing resources or processing external data in Terraform.
  5. Output: The output block allows you to specify values that should be displayed when Terraform is run, such as the IP address of a virtual machine or the URL of a website.

These are the main components that make up a Terraform configuration file. By combining these components in different ways, you can define the complex infrastructure and automate the management of your resources with Terraform.

Deploying Servers in AWS

Setup aws-cli

To deploy, we will also need the credentials of our AWS Account present in our system. We will use the aws-cli tool provided by AWS to do so.

Run the following commands.

brew install awscli
aws configure
AWS Access Key ID [****************FFZR]: RANDOM_VALUE_XYZFFZR
AWS Secret Access Key [****************/m40]: RANDOM_VALUE_XYZ/m40
Default region name [ap-south-1]: ap-south-1
Default output format [json]: json
Output of aws configure

Now, check if our user account has been registered with aws-cli.

Run the following command.

aws iam get-user
{
    "User": {
        "Path": "/",
        "UserName": "random-dummy",
        "UserId": "RANDOM_USER_ID_IA2MW7",
        "Arn": "arn:aws:iam::AUTO_GEN_NUM:user/random-dummy",
        "CreateDate": "2022-12-05T10:48:54+00:00",
        "PasswordLastUsed": "2023-02-08T01:43:03+00:00",
        "Tags": [
            {
                "Key": "Name",
                "Value": "random-dummy"
            }
        ]
    }
}
Output of aws iam get-user
Setup Terraform Code

Let's create a directory where we will store the project files.

mkdir -p terraform-projects/aws-ec2-demo
cd terraform-projects/aws-ec2-demo
touch main.tf

Paste the following code into the main.tf file.

provider "aws" {
  region = "ap-south-1"
}

resource "aws_vpc" "example" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "example" {
  vpc_id = aws_vpc.example.id
  cidr_block = "10.0.1.0/24"
}

resource "aws_security_group" "example" {
  name        = "example"
  description = "Allow HTTP and SSH traffic"

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  subnet_id     = aws_subnet.example.id
  vpc_security_group_ids = [aws_security_group.example.id]

  tags = {
    Name = "example-instance"
  }

  connection {
    type        = "ssh"
    user        = "ec2-user"
    private_key = file("~/.ssh/id_rsa")
  }
}

resource "aws_ebs_volume" "example" {
  availability_zone = aws_instance.example.availability_zone
  size              = 10
}

resource "aws_volume_attachment" "example" {
  device_name = "/dev/xvdf"
  volume_id   = aws_ebs_volume.example.id
  instance_id = aws_instance.example.id
}
Terraform code to initiate infrastructure in Terraform
Codesplained

The configuration in the above provided Terraform Code (HCL Code) does the following:

  1. Defines the AWS provider and the region to use.
  2. Creates a VPC with a CIDR block of 10.0.0.0/16.
  3. Creates a subnet within the VPC with a CIDR block of 10.0.1.0/24.
  4. Creates a security group that allows incoming SSH and HTTP traffic and allows all outgoing traffic.
  5. Provisions an EC2 instance with the specified AMI, instance type, subnet, and security group.
  6. Creates an EBS volume of 10 GB in the same availability zone as the EC2 instance.
  7. Attaches the EBS volume to the EC2 instance.

Use the following commands to start infra deployment (or delete the deployed infrastructure if you have done so already).

# Initializes the TF File (Installs required dependencies)
terraform init

# Works like a dry run, the infra will not be created but the changes that will be made during new provisions or updates on existing infra managed via terraform will be highlighted
terraform plan

# Permanently applies the changes
terraform apply

# If you want to delete the provisioned infra (optional - only for deletion)
terraform destroy
Main Commands of Terraform

Conclusion

In this article, we learned to provision infrastructure on AWS using Terraform. We also learned about the different components that make up the Terraform File.

Please comment below if you have any queries or discover any inaccuracies in the article. I revisit my articles to make corrections as required by updates in the technologies that I use.