Project: Build the infrastructure using Terraform and write a CICD pipeline to deploy the notes app

Project: Build the infrastructure using Terraform and write a CICD pipeline to deploy the notes app

Hello everyone, in this project we are going to build the infrastructure using Terraform and then we will write a Jenkins pipeline to build an image, push it to docker, and then deploy it.

Steps to provision the infrastructure -

  1. Write the Terraform files -

Terraform.tf - We need AWS provider to provision AWS EC2 instances.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

providers.tf -

provider "aws" {
  region = "us-east-1"
}

Variables.tf - Declaring variables (We are using a key pair that already exists)

variable "ami" {
  default = "ami-053b0d53c279acc90"
}

variable "instance_type" {
  default = "t2.micro"
}

variable "region" {
  default = "us-east-1"
}

variable "key-pair" {
  default = "BashBlaze-key"
}

servers.tf - (We are using a security group that already exists)

data "aws_security_group" "launch-wizard-3" {
  name = "launch-wizard-3"
}

resource "aws_instance" "Jenkins-Server" {
  instance_type = var.instance_type
  ami = var.ami
  key_name = var.key-pair
  user_data = file("${path.module}/Jenkins-master.sh")
  vpc_security_group_ids = [data.aws_security_group.launch-wizard-3.id]
  tags = {
    Name = "Jenkins-Server"
  }
}

resource "aws_instance" "Jenkins-Agent" {
  instance_type = var.instance_type
  ami = var.ami
  key_name = var.key-pair
  user_data = file("${path.module}/Jenkins-agent.sh")
  vpc_security_group_ids = [data.aws_security_group.launch-wizard-3.id]
  tags = {
    Name = "Jenkins-Agent"
  }
}

Jenkins-agent.sh - Creating a file for user data to install java and docker in the agent server, also providing the permissions to run docker commands to ubuntu user.

#!/bin/bash
sudo apt update
sudo apt install openjdk-17-jre -y
sudo apt install docker.io docker-compose -y
sudo usermod -aG docker $USER 
sudo reboot

Jenkins-master.sh - Creating a file for user data to install Jenkins in the master server

#!/bin/bash
sudo apt update
sudo apt install openjdk-17-jre -y
curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee \
  /usr/share/keyrings/jenkins-keyring.asc > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
  https://pkg.jenkins.io/debian binary/ | sudo tee \
  /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins -y
  1. Once the files are created, run terraform init and terraform apply commands -

  1. Validate the EC2 instances in the AWS console.

  1. Log in to the master server - Generate Key pairs and establish SSH authentication between Jenkins master and agent servers.

    • Run command - ssh-keygen to generate keypairs

  • Copy the public key of the master server to the agent server's authorized_keys

  1. Setup the Jenkins UI

  2. Setup and agent

  1. Create a new node as per the below screenshots(Please ignore the hostname as Ubuntu in the below screenshots, I have updated it later with the IP of the agent node)

  1. Create credentials for SSH authentication -

  • Give the private key of the master server directly.

  1. Update the host IP and credentials and strategy as non verifying strategy.

  1. The new node should be connected.

  1. We need to create docker credentials to push the image to the docker hub -

    Go to Manage Jenkins > Credentials > Add Credentials >

  1. Give the username and password of the docker hub account.

  1. Create an empty repo in docker hub -

  1. Create a new pipeline in Jenkins - Give the Github URL

  1. Write the Jenkins pipeline as below -

    • Here, we are running the pipeline on agent-dev (which is our agent server)

    • Steps :

      • Fetching the code

      • Building the code using docker

      • Pushing the image to docker using credentials that we created earlier.

      • Deploying the code

  1. Once the pipeline is ready, build the pipeline

    • Our app is up and running now.

  1. We will deploy the application using the GitHub webhooks.

  2. Go to GitHub and GitHub repository settings and create a webhook -

  3. I have updated a new commit in the Github repo which triggered a build automatically making the process end-to-end automated -

  1. Once you are done with the project, tear down the infrastructure by running a single command - terraform destroy

Thank you :)