Automation Master - Jenkins

Automation Master - Jenkins

Complete CI-CD Pipeline

When we were in college we used to pass slambook to each other for collectiong friends data like name, dob, hobbies etc and i took same theory to create my slambook-two-tier appliaction.

In this web application -

  1. Front End - A simple form for collecting friend data, written in HTML.

  2. Back End - I used the Flask Python web framework for the backend.

  3. Database - I used MySQL as the database, which stored the data of friends in a MySQL container.

I used this application to set up a complete CI/CD pipeline.

  1. Set up Jenkins

  2. Set up a Node agent

  3. Set up a GitHub webhook trigger

  4. Create a Pipeline

  5. Create a Jenkinsfile

Setup Jenkins

To install Jenkins in system need to install Java first in the system, without Java installlation Jenkins won't run.

sudo apt update
sudo apt install fontconfig openjdk-17-jre
java -version
openjdk version "17.0.8" 2023-07-18
OpenJDK Runtime Environment (build 17.0.8+7-Debian-1deb12u1)
OpenJDK 64-Bit Server VM (build 17.0.8+7-Debian-1deb12u1, mixed mode, sharing)
sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \
  https://pkg.jenkins.io/debian/jenkins.io-2023.key
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
  • Set admin username and pasword for Jenkins

  • Install required Plugins

  • Once complete login with username and password

Setup Node agent

To set up the node agent, I am using an EC2 instance because my Jenkins server is on my Ubuntu system.

To set up the agent, we need to extract the private and public keys from the master or Jenkins server.

  • Extract the private and public keys using ssh-keygen
cd .ssh
ssh-keygen
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/amitt-ashok/.ssh/id_ed25519): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/amitt-ashok/.ssh/id_ed25519
Your public key has been saved in /home/amitt-ashok/.ssh/id_ed25519.pub
The key fingerprint is:
amitt-ashok@Bajrang:~/.ssh$ ls
id_ed25519  id_ed25519.pub  known_hosts  new-key  new-key.pub
  • Copy the public key from the master node.

  • Once copied, navigate to the agent's .ssh folder and paste the public key into the authorized_keys file.

  • Check if you can now log in from the master to the agent using the SSH key.

ssh ubuntu@13.232.40.240
The authenticity of host '13.232.40.240 (13.232.40.240)' can't be established.
ED25519 key fingerprint is SHA256:iwF1o4tH244OjClXV9UH+Nz7n3RWWogsjGvLizqBKTQ.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '13.232.40.240' (ED25519) to the list of known hosts.
Welcome to Ubuntu 24.04 LTS (GNU/Linux 6.8.0-1009-aws x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Sun Aug  4 15:53:34 UTC 2024

  System load:  0.0               Processes:             108
  Usage of /:   22.9% of 6.71GB   Users logged in:       1
  Memory usage: 21%               IPv4 address for enX0: 172.31.3.191
  Swap usage:   0%


Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


The list of available updates is more than a week old.
To check for new updates run: sudo apt update

Last login: Sun Aug  4 15:38:38 2024 from 103.191.204.136
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

ubuntu@ip-172-31-3-191:~$

Once the connection is established, set up this agent in Jenkins:

  • Open Jenkins and go to "Manage Jenkins".

  • Under system configuration, check the "Nodes" section and click on "New Node".

  • Give a name to the agent; here, I am naming it "agent-deploy". Then, select the radio button for "Permanent Agent".

  • Provide a description for the agent.

  • Enter the remote root directory - this is the location where code and other details will be saved.

  • Give a label for the agent.

  • For the launch method, select "Launch agent via SSH" since we have already set the public SSH key in the agent node.

  • In the host section, provide the public IP address of the EC2 instance.

  • To add credentials, click the add button. This will take you to a new form where you need to select the type and choose "SSH Username with private key."

  • Fill in the other details: ID, description, and username.

  • For the private key, select "Enter directly" and click add. Here, you need to enter the private key of the master node.

  • Now check if the node is connected properly. Remember, you need to have Java installed on the agent node to make a successful connection.

  • Now, "agent-deploy" is connected successfully and in sync.

Setup Github webhook Trigeer

A trigger is used to automate code from GitHub, ensuring a new job runs with the updated code.

To set up a GitHub webhook on my system, since my Jenkins server is running locally, I am using ngrok to create a tunnel for port 8080.

Download ngrok if you are using your own system and not an AWS EC2 instance.

 curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null && echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | sudo tee /etc/apt/sources.list.d/ngrok.list && sudo apt update && sudo apt install ngrok

Enter ngrok http 8080 to create a tunnel from your system.

amitt-ashok@Bajrang:~/.ssh$ ngrok http 8080
ngrok                                                                                                                  (Ctrl+C to quit)

Help shape K8s Bindings https://ngrok.com/new-features-update?ref=k8s                                                                  

Session Status                online                                                                                                   
Account                       amitt ashok (Plan: Free)                                                                                 
Version                       3.14.0                                                                                                   
Region                        India (in)                                                                                               
Web Interface                 http://127.0.0.1:4040                                                                                    
Forwarding                    https://1339-103-191-204-136.ngrok-free.app -> http://localhost:8080                                     

Connections                   ttl     opn     rt1     rt5     p50     p90                                                              
                              0       0       0.00    0.00    0.00    0.00

This will create a new forwarding URL, and we need to use this URL to set up the GitHub webhook.

  • Copy the URL and navigate to your GitHub account. Select the code repository, then go to the settings section. Look for the webhook option and select "Add webhook" there.

  • A green checkmark indicates that the webhook trigger is connected properly.

Create CI/CD Pipeline

  • Select "New Item" and choose the "Pipeline" option.

  • Enter an appropriate description for the pipeline job.

  • For code management, select "GitHub Project" and enter the repository URL from GitHub.

  • In build triggers section select for Github hook triggers and select pipeline option to write the pipeline

pipeline {
    agent {label 'agent-deploy'}

    stages {
        stage("Code Clone") {
            steps {
                git url: "https://github.com/AmittAshok/Slam-book.git", branch: "master"
            }
        }
        stage("Code build") {
            steps {
                sh 'docker build . -t amittashok/slambook-cicd:latest'
            }
        }
        stage("login and push") {
            steps {
                echo "Building the code and pushing to Docker Hub"
                withCredentials([usernamePassword(credentialsId: 'docker-hub', passwordVariable: 'docHubPassword', usernameVariable: 'docHubUsername')]) {
                    sh "docker login -u ${env.docHubUsername} -p ${env.docHubPassword}"
                    sh "docker push amittashok/slambook-cicd:latest "
                }
            }
        }

        stage("Code Run") {
            steps {
                sh 'docker compose down'  // Use 'docker-compose' if using Docker Compose v1
                sh 'docker compose up -d'  // Use 'docker-compose' if using Docker Compose v1
            }
        }
    }
}
  • Here, I want to run my pipeline on an agent node, so I have labeled the agent as 'agent-deploy'.

  • There are four stages

    • Code Clone - Clone the code from the GitHub repository

    • Code Build - Create an image using the Docker build command

    • Login and Push - Push the created image to Docker Hub. To set up the username and password in the environment, you need to add the environment plugin in Jenkins and then add Docker Hub credentials in the credentials section of Jenkins.

    • Code Run - Deploy the code and create two containers: one for the application and one for MySQL

Two containers were created on the agent node and are running successfully.

ubuntu@ip-172-31-3-191:~$ docker ps -a
CONTAINER ID   IMAGE                             COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
e563484ad2ec   amittashok/slambook-cicd:latest   "python app.py"          12 minutes ago   Up 12 minutes   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp              slambook-project-web-1
d430066f04c8   mysql:5.7                         "docker-entrypoint.s…"   12 minutes ago   Up 12 minutes   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   slambook-project-mysql-1
ubuntu@ip-172-31-3-191:~$

To run the application on an EC2 instance, open port number 5000.

Create Jenkinsfile

To create a Jenkinsfile, simply copy the pipeline code and paste it into the Jenkinsfile of your GitHub repository.

Now, with this Jenkinsfile, we can easily create a complete CI/CD pipeline.

To summarize this article, we have shown how to create a complete CI/CD pipeline and then create the Jenkinsfile from it.

Thank You for the day...

See you soon...