Complete CI/CD pipeline 
Tags: devops, jenkins, docker, kubernetes
Published: 2022-02-24 18:50:16

A CI/CD pipeline is a series of steps that must be performed in order to deliver a new version of the software. Continuous integration/continuous delivery (CI/CD) pipelines are a practice focused on improving software delivery using either a DevOps or site reliability engineering (SRE) approach.

I've created a simple CI/CD pipeline with -  

- GitHub for SCM.
- Jenkins.
- Docker. 
- Docker Hub.
- AWS EC2 Instances.
- AWS EKS service.

### Let's begin!

## Step 1

### Create an EC2 instance to run Jenkins.
I'm going to create an AWS EC2 instance and install docker in it to run Jenkins. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g1oiyn4c1zw0xi38kp93.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dfa5ljnjglainq7g1wd7.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9tao9avg7neyvm9meh90.png)

It is best practice for a user to access Jenkins with limited permission, so let's create a Jenkins user for this purpose.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/my2iynp3d2u8rz066xra.png)

Once this Jenkins container is up, edit the inbound rules to expose port 8080. 
 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ts0u719p56nxznor3khc.png)

Let's finish up the initial settings 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n4dpngquru1xu6jhg56n.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c934dotytftr7e8ikzm7.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yieyuom58i2hukbh3dmf.png)
 
You need to make the data persist even after you restart the server. 
So, stop the container, re-run docker the volume defined. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dfgvr9nmp4y3gy81mr98.png)

Next, provide the required access to docker.

Login as root user.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i9a8hnorrront8qfj8ye.png)
 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xj6lrxspoazjv8n7h0a2.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0vtw3j9itbhxbl4j61i5.png)
 
So, we now have Jenkins up and running. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dbr2zku9evdn3kca23vq.png)

 

## Step 2

### Push your code to GitHub.

For this project, we will use the Java Maven App with a Postgres database.

You can clone my project for your reference - [Repo Link](https://github.com/akshayca/ci-cd-project.git)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9aq2feffcb0z3bmledg2.png)


Here is the list of tasks that needs to be performed by Jenkins -

1. Build the solution and increment the version number.
2. Build the Docker Image using the Dockerfile and push the Image to the DockerHub. 
3. Trigger the automation tests.
4. Deploy the App to a K8s cluster.
5. Commit version update to SCM. 


## Step 3 

### Create a simple pipeline project in Jenkins. 

- Set GitHub hook trigger for GITScm polling
- Provide the Git Repository URL and credentials
- Script Path as Jenkinsfile

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nknw2pskmp4wvk7boxo2.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qbr9ip239vv0uxmgartd.png)
 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/119liwp90krs895ob04l.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ce206bdkfor5ybygfqdq.png)
  
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4fjykcamfxjnh8q6kvn0.png)

## Step 4

### Create Jenkins shared library. 

Jenkins Shared Libraries are written in Groovy and allow you to create common sets of logic, and share that among teams/projects/organizations.

I've created one for this project - [Repo Link](https://github.com/akshayca/jenkins-shared-library)
 
Update your Jenkins file to read the shared library. 

 ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bujf85lwj7qok6e4awny.png)

Increment version-
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4p5c7fgnkdnt07zho7kx.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oi32jprybicnee62mbwu.png)
 
Build the Jar-
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kokpka9py7ag4orw00q.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ac4v733pht6d9qdbzv8z.png)

Build the Docker Image and Push it to the DockerHub -
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qyx6jqsh2jtebawkohmb.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u0u18epmys1gugv6copv.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ns5zd53hz3ryz4qsichi.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bm8agytmniwbzaazagas.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3a6adte55dplmuysywm7.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/26129jbvkq3l9fg7d3yx.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9byc5ybqwwleuztr6mdl.png)
 
Now if everything is configured properly, whenever you push your code to the master. Jenkins should trigger the pipeline and perform the below actions. 
- Clone the git repository
- Increment the version number
- Build the Jar file
- Build Docker Image
- Push the Image to Docker Hub
 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xkz5bbqj0vgebwblmfdq.png)

## Step 5

### Deploy to K8s cluster

Now we are supposed to trigger the automation tests. Once all the tests are passed and all the checklists are cleared, we can deploy our App to the production.

Install **Kubectl** command-line tool inside Jenkins container.
Install **aws-iam-authenticator** tool inside Jenkins container.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8cbcglsx8ys22yzy7mi9.png)

I've create an EKS cluster called demo-cluster.
 ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k0ww448mucl0p8eoxsd7.png)
 ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7xqlvs0wwiu6pjhfigc7.png)

Create **Kubeconfig** file to connect to EKS cluster.
- contains all the necessary for authentication 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4lmq5v73ue5oiifd5ek7.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zefw9wyaai0nqhcyyy66.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vzomwtvqne7b9e149e4a.png)
 
Add **AWS credentials** on Jenkins for AWS account authentication
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x4ej84folghdkurx8322.png)
 
Adjust **Jenkinsfile** to configure EKS cluster deployment.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9314ga0byeq4ct6d82ex.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a26z3pzzxqy7hmod0cde.png)
  
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nup3m9766i0bv274v0pk.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8u1fgwjuq2dgt8vect1t.png)
 
The last thing which you need to do once the deployment is successful is to commit the version update to the code repository.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ghe6n6bxdooin9k1w8y.png)
 
### The pipeline is now complete. 

## Now let's run it !!!

Push some changes to the Master branch our pipeline will be triggered.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bnfoarikxzytpfv4k3o1.png)
 
### Check the logs
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/svutf7xit15qebx4ns9p.png)
 ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ku9pgnz6i517vqn8pkdc.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y2a9fmafastivep4r8b3.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4yh87t16zpwuu8k6ig06.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eug9lmsq402iafux0wj4.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u9yrpdn3px233gmaf0q0.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jv73f033h8tjun6i1ona.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/opp22molcj71q5f3wp5m.png)


### Now let's connect to the EKS cluster from our local machine to verify.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c7h5thbq3wobz801q2ch.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/irl2twk1g02r5z1nhlc8.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2gvnbj0jnqd1zw2d7ztt.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hbc873swrymhtpljueh0.png)
 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/acnfbd6ca0mismk990fp.png)

Thank you! 
Please comment for feedback. 
Happy learning :)


#### Overview of our CI/CD pipeline -

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/maummpyg4539j9nbcts8.png)