Automate AWS Infrastructure Deployment using Terraform and GitHub Actions

ยท

10 min read

Automate AWS Infrastructure Deployment using Terraform and GitHub Actions

What is IaC?

IaC means Infrastructure as Code it is a tool used to create resources on cloud providers like AWS, Azure, GCP, Oracle, and a long list. For example, if you want to create an EC2 instance using the IaC tool, rather than going to the management console and clicking on the service you will write a code to create an EC2 instance, using IaC it is very easy to manage the infrastructure, you can reuse the code to create multiple resources, you can also store your code on version control system like GitHub, GitLab to keep a track of your change.

Why do we need IaC?

Let's consider a company that needs to set up and manage its IT infrastructure, including servers, databases, and networking. Here's how an Infrastructure as Code (IaC) tool can benefit them using a simple example:
Without IaC: Imagine the company needs to set up servers for a new project. They would manually log into each server, install software, configure settings, and repeat this process for every server. If they need to make changes or scale up, they have to do it all over again, which is time-consuming and prone to errors. Additionally, different team members might set things up differently, leading to inconsistencies.
With IaC: Now, if the company uses an IaC tool like Terraform, they can write code that defines the servers, software, and configurations they need. This code acts like a blueprint. Whenever they need more servers or changes, they update the code and run the IaC tool. It automatically creates the servers exactly as defined in the code. This ensures consistency, speeds up setup, and reduces the chances of errors.
Some of the IaC tools are Terraform, Chef, CloudFormation, Azure Resource Manager (ARM) Templates, and Google Cloud Deployment Manager

What is terraform?

Terraform is an IaC tool that allows you to define and manage your computer infrastructure using code. It's like providing a set of instructions to build and manage your digital environments, such as servers, databases, networks, and other resources. This code-based approach makes it easier to create, modify, and scale your infrastructure while keeping everything consistent and organized. Terraform helps you automate the process of setting up and maintaining your technology foundation, saving time and reducing errors in managing complex systems.

Why Terraform?

Terraform remains the number one Infrastructure as a Code tool as far as the cloud is concerned, because of some reasons.
First-Mover Advantage:- Terraform is the first IaC tool with a complete set of features.
Cloud Neutral:- As Terraform can be used for cloud provision resources on AWS, Azure and Google Cloud.
HashiCorp control Language:- This is the language in which we write our terraform script and it is a very simple language to learn and make use of.

How does Terraform work?

So, how does Terraform do all this, how does Terraform connect to the platform providers, How does Terraform connect to AWS to create Virtual space and do configure networking, etc
To do the job Terraform has two main components that make up its architecture.
The first one is Terraform core which has two input sources one takes Terraform configuration which is TF-file in which the user defines or writes what needs to be created and the second one is Terraform state which is State-file in which Terraform keeps the up-to-date state of how the current set up of the infrastructure looks like so what Terraform core does is it takes the inputs and figure out the plan of what needs to do be done. So it compares the current state and what is the configuration that you desire as the end result then it figures out what needs to be done to get that desired state in the configuration file so what needs to be created, what needs to be updated, or what needs to be deleted and in which order on that infrastructure.

An understanding of Terraform architecture | HashiCorp Infrastructure  Automation Certification Guide

The second one is Providers of specific technologies, this could be Cloud Providers like AWS, Azure, Google Cloud, or other Infrastructure as a service platform [IaaS] it also has more high-level components like Kubernetes or other Platform as a service [PaaS] tools and even some Software as a Service[SaaS].
So all this gives you the possibility to create stuff on different levels like create an AWS infrastructure then deploy or create Kubernetes on top of it and then create services inside that Kubernetes cluster so it gives all these possibilities and it does that through those providers.
Terraform has hundreds of providers for these different technologies and each provides then give user access to its resources. So this way Terraform helps to provision and cover the complete application setup from infrastructure to the application setup.

What is Terraform Cloud? Complete Terraform Tutorial [New]

Terraform Commands and Workflow

Commands

Terraform init prepares your project. It sets up tools and plugins, ensuring Terraform understands your code and connects to your cloud provider correctly before you start working.
Terraform validate checks your Terraform code for syntax errors and basic structure problems. It's like spell-check for your infrastructure instructions.
Terraform plan shows what Terraform will create or change before you apply it. It's like previewing before building, helping you avoid surprises in your infrastructure changes.
Terraform apply builds or updates your infrastructure based on your code. It turns your plans into reality, creating resources as defined in your Terraform configuration. Terraform destroy is like a delete button for your infrastructure. It uses your code to tear down resources, helping you safely remove what you've built when it's no longer needed.

terraform fmt tidies up your Terraform code, making it neat and consistent. It's like auto-correct for your code, making it easier to read and understand.
terraform providers lists the providers (like AWS, Azure) used in your project. It's like seeing which tools you'll use to build your tech stuff.

Link for the resource definitions in Terraform

Download Terraform

For macOS:-

brew tap hashicorp/tap
brew install hashicorp/tap/terraform

For Linux:-

wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform

For verifying:-

terraform version

Creating AWS infrastructure using Terraform

Needed resources to create infrastructure

  1. VPC (Virtual Private Cloud): Secure isolated cloud environment in AWS to host resources, like servers and databases, with controlled network settings.

  2. Internet Gateway: Connects VPC to the internet, allowing resources within the VPC to access and be accessed by the internet.

  3. Route Table: Manages traffic between subnets and the internet, directing data to the right destinations within the VPC.

  4. Subnet: Segments of VPC's IP range, providing isolated environments for resources. It can be public (internet-facing) or private.

  5. Security Groups: Virtual firewalls that control inbound and outbound traffic to resources, enhancing security and access control.

  6. EC2 Instance: Virtual server in AWS, allowing you to run applications, databases, and more within your VPC.

Setup Access Key and Secret Access Key

For getting these key you need to go to your AWS account -> My Security Credentials -> navigate to Access Keys -> click on the Create New Access Key

It will give you AWS Access Key ID, AWS Secret Access Key.

This will give you Acess Key and Secret Access Key.

This will appear for once only, so to keep it saved, you should copy it and save it somewhere because as you close it will be gone.

Writing Terraform script

To create an AWS infrastructure first user need to write Terraform script file in which the user needs to describe what needs to be created. In my project, I am using three Terraform files.

  1. main.tf - Infrastructure Description: In the main.tf file, you define the structure, resources, and configuration of your infrastructure. It contains detailed instructions for creating servers, databases, networks, and more. This is where you specify your desired tech environment.

  2. providers.tf - List of Providers: The providers.tf file lists all the cloud providers you're using, like AWS, Azure, or others. It specifies how Terraform connects to each provider. This file ensures Terraform knows where to build your tech stuff.

  3. variables.tf - Managed Variables: In variables.tf, you store the variables used in your main.tf or providers.tf files. This is like a control center for your project's settings. By centralizing variables here, you make it easy to adjust or expand your tech setup without diving into code.

provider.tf

provider "aws" {
  region  = "ap-south-1"
  access_key = "<provider access key>"
  secret_key = "<provider secret key>"
}

main.tf

//  create VPC

resource "aws_vpc" "first-vpc" {
  cidr_block = "10.10.0.0/16"
}

//  create Subnet

resource "aws_subnet" "first-subnet" {
  vpc_id     = aws_vpc.first-vpc.id
  cidr_block = "10.10.1.0/24"

  tags = {
    Name = "subnet"
  }
}

//  create Internet Gateway

resource "aws_internet_gateway" "first-igw" {
  vpc_id = aws_vpc.first-vpc.id

  tags = {
    Name = "Internet Gateway"
  }
}

//  create route table

resource "aws_route_table" "first-rt" {
  vpc_id = aws_vpc.first-vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.first-igw.id
  }


  tags = {
    Name = "route table"
  }
}

//  create associate subnet with route table

resource "aws_route_table_association" "first-rta" {
  subnet_id      = aws_subnet.first-subnet.id
  route_table_id = aws_route_table.first-rt.id
}

//  create security group

resource "aws_security_group" "allow_tls" {
  name        = "allow_tls"
  description = "Allow TLS inbound traffic"
  vpc_id      = aws_vpc.first-vpc.id

  dynamic "ingress" {
    for_each = var.ports
    iterator = port
    content {
      description      = "TLS from VPC"
      from_port        = port.value
      to_port          = port.value
      protocol         = "tcp"
      cidr_blocks      = ["0.0.0.0/0"]
      ipv6_cidr_blocks = ["::/0"]

    }
  }

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

  tags = {
    Name = "allow_tls"
  }
}

//  create EC2 instance

resource "aws_instance" "first-instance" {
  ami                    = "ami-0f5ee92e2d63afc18"
  instance_type          = "t2.micro"
  subnet_id              = aws_subnet.first-subnet.id
  vpc_security_group_ids = [aws_security_group.allow_tls.id]

  tags = {
    Name = "First-terraform-instance"
  }

}

variable.tf

variable "ports" {
  type = list(number)
 default = [22, 80, 443, 3306]
}

Run Your Terraform script into the terminal

First, we need to give terraform init command to Initialize all the backend and provider plugins

We can check all the plugins and providers by doing terraform providers command

Now we can validate our terraform script by doing terraform validate command

By doing terraform plan command we can actually check what change it will bring, if we apply the terraform script.

Now by doing terraform apply command, we can run our terraform script

Your AWS Infrastructure is created over your aws account.

All the resources that you have mentioned in the Terraform script are created.

EC2 instance

VPC

Subnet

Security Group

Automate it by GitHub Actions

Now, go to your GitHub profile, click the repository section, and create a New repository.

Push your code to your new repository.

To integrate GitHub Actions into the project, create a .github/workflows directory within the core of your project directory. Inside this directory, you'll write a YAML file to define the specific GitHub Actions to be executed for your project.

Write down your terraform.yaml file.

name: "Terraform Workflow"

on:
  push:
    branches:
      - main

jobs:
  terraform:
    runs-on: ubuntu-latest

    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v1

      - name: Format Terraform files
        run: terraform fmt -check

      - name: Initialize Terraform
        run: terraform init

      - name: Plan Terraform changes
        run: terraform plan

      - name: Apply Terraform changes
        run: terraform apply -auto-approve

Remember that for the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, it's recommended to use GitHub Secrets to securely store and access your AWS credentials. You can add these secrets in your repository settings on GitHub.

After that push your code to your GitHub repo, as that will trigger the Continuous Integration in Github action and will automatically build the steps written in your Terraform.yaml file

The presence of a yellow dot adjacent to a repository signifies that an associated GitHub Action workflow is actively executing. Upon accessing the repository, the workflow's progress is displayed, delineating the specific steps and processes currently being undertaken by the GitHub Action.

An Instance is created by Github-Action and Terraform.

๐ŸŽ‰ Congratulations on Creating your AWS Infrastructure using Terraform and GitHub! ๐ŸŒ๐Ÿš€

Conclusion

So we have come to the end of this blog this blog took us step by step through building a strong AWS setup using Terraform. We customize a VPC and got an EC2 instance up and running. We saw how GitHub action adds automation. By joining Terraform and GitHub Actions, we found a way to make cloud handling simpler. In case you have any doubts regarding this, feel free to DM me.

If you found this blog helpful, do like and comment your thoughts.
Thanks for reading. ๐Ÿค—๐Ÿ’™

ย