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 -
- 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"
}
}
}
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
- Once the files are created, run
terraform init
andterraform apply
commands -
- Validate the EC2 instances in the AWS console.
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
- Run command -
- Copy the public key of the master server to the agent server's
authorized_keys
Setup the Jenkins UI
Setup and agent
- 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)
- Create credentials for SSH authentication -
- Give the private key of the master server directly.
- Update the host IP and credentials and strategy as non verifying strategy.
- The new node should be connected.
We need to create docker credentials to push the image to the docker hub -
Go to Manage Jenkins > Credentials > Add Credentials >
- Give the username and password of the docker hub account.
- Create an empty repo in docker hub -
- Create a new pipeline in Jenkins - Give the Github URL
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
Once the pipeline is ready, build the pipeline
- Our app is up and running now.
We will deploy the application using the GitHub webhooks.
Go to GitHub and GitHub repository settings and create a webhook -
-
I have updated a new commit in the Github repo which triggered a build automatically making the process end-to-end automated -
- Once you are done with the project, tear down the infrastructure by running a single command -
terraform destroy
Thank you :)