Automated CI/CD Pipeline Implementation using Jenkins, SonarQube, Nexus, Docker, and Deploying in Kubernetes using ArgoCd
Introduction
Here in this Project, we will deploy the simple JAVA application on Kubernetes following the CI/CD practices. We will use Jenkins as our Continuous Integration tool and we use ArgoCd as a CD part and deploy our app in Kubernetes using it. We use tools like Maven for building the app, for UNIT and Integrated testing and then we will send the artifacts in Nexus, sonarqube for the static code analysis, use Docker to build the images and push them to the docker hub.
Setup an AWS EC2 Instance
Login to an AWS account using a user with admin privileges and ensure your region is set to us-east-1 N. Virginia. Move to the EC2 console. Click Launch Instance.
We first Create two(2) AWS EC2 Instances where we will install all Jenkins and sonarQube in one EC2 instance whereas in another EC2 we will install Nexus in another.
Select AMIs as Ubuntu and select Instance Type as t3.medium. Create new Key Pair and Create a new Security Group with traffic allowed from ssh, http and https.
Continuous integration(CI)
Install and Setup Jenkins
Follow the steps for installing Jenkins on the EC2 instance.
sudo apt update
sudo apt install openjdk-17-jre -y
java -version
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
sudo systemctl start jenkins
sudo systemctl enable jenkins
sudo systemctl status jenkins
You can get the ec2-instance-public-ip-address from your AWS EC2 console page.
Edit the inbound traffic rule to only allow custom TCP port 8080
http://:<ec2-instance-public-ip-address>8080.
Install Java and Jenkins on Jenkins Server and configure port 8080 as we have done so many times in our previous blogs. You can follow my previous blogs: https://nahid0002.hashnode.dev/mastering-cicd-with-jenkins-building-and-deploying-applications-with-efficiency
Also, you can follow Jenkins official's documents: https://www.jenkins.io/doc/book/installing/linux/
Configure a Sonar Server locally
SonarQube is used as part of the build process (Continuous Integration and Continuous Delivery) in all Java services to ensure high-quality code and remove bugs that can be found during static analysis.
Goto your EC2 Instance and enter these commands to configure Sonar Server
sudo adduser sonarqube
<Enter any password when it prompts you>
sudo apt install unzip
sudo su - sonarqube
When you enter sudo su — sonarqube, you will switch user to sonarqube and then install the required binaries.
wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-9.4.0.54424.zip
unzip *
chmod -R 755 /home/sonarqube/sonarqube-9.4.0.54424
chown -R sonarqube:sonarqube /home/sonarqube/sonarqube-9.4.0.54424
cd sonarqube-9.4.0.54424/bin/linux-x86-64/
./sonar.sh start
By default, the Sonar Server will start on Port 9000. Hence we will need to edit the inbound rule to allow custom TCP Port 9000.
Enter Login as admin and password as admin.
Change with a new password
Nexus Server Install and Setup:
Installing Nexus on the EC2 instance.
Access Nexus Repository Web Interface
To access the Nexus repository web interface, open your favourite browser. You can get the ec2-instance-public-ip-address from your AWS EC2 console page. Edit the inbound traffic rule to only allow custom TCP port 8081
http://:<ec2-instance-public-ip-address>8081.
you will see below the default Nexus page
To login to Nexus, click on Sign In, default username is admin
To find the default password run the below command
cat /opt/nexus/sonatype-work/nexus3/admin.password
copy the default Nexus password and login, you can reset the password once logged in to Nexus
sudo cat /opt/sonatype-work/nexus3/admin.password
Change the default Nexus admin password
configure Anonymous Access
click on Finish.
That's it! You've successfully installed Nexus Repository Manager on your EC2 Ubuntu instance. You can now use it to manage your repositories.
Log in to the Nexus server and create a repository Here:
We will create a new repository named demoapp-release in the Nexus Server creating a custom repository as maven ( hosted ).
Create SonarQUbe Credential in Jenkins
Goto Sonar Qube → My Account → Click on Security → Write Jenkins and click on Generate
Next, goto your Jenkins → Manage Jenkins → Manage Credentials →System →Global Credentials → Add Credentials →
Install Docker
Run the below commands as the root user to install Docker
sudo su -
sudo apt update
sudo apt install docker.io -y
sudo usermod -aG docker $USER
sudo usermod -aG docker jenkins
sudo systemctl restart docker
#Once you have done these, its a best practice to restart Jenkins
sudo systemctl restart jenkins
Create DockerHub Credential in Jenkins
Goto -> Jenkins -> Manage Jenkins -> Manage Credentials -> Stored scoped to jenkins -> global -> Add Credentials
Create Nexus server credentials in Jenkins
Goto -> Jenkins -> Manage Jenkins -> Manage Credentials -> Stored scoped to Jenkins -> global -> Add Credentials
→Select a username and password option
→ username: admin
→ password: Your Nexus password
→ id: nexus-auth
Then click on the Create button.
Create GitHub credential in Jenkins
Goto GitHub — > Setting — > Developer Settings — > Personal access tokens — > Tokens(Classic) — > Generate new token
Install required plugins on the Jenkins server:
Here We will install Maven Integration, GitHub Integration, Nexus Artifact Uploader, SonarQubeScanner
Pipeline
Jenkinsfile we provide to Jenkins is used for automating our tasks. The Maven used for the build and test of our application looks out for pom.xml file for installing the required dependencies for building the app.
We configure the required credentials of Sonarqube, Docker, Nexus and GitHub.
After configuring we again restarted the Jenkins server.
As per the Jenkinsfile ( mentioned above), docker is used as an agent to build the container required to run the steps.
After creating a new item and adding your GitHub repository click Build now
First, check if Jenkins can clone the GitHub file or not.
We had done testing. Both the Unit testing and integrated testing. We perform these tests with the help of Maven. We use Maven to build our app and get the jar/war file which we send the jar file to Nexus.
Here, sonarqube is used for the static code Analysis and Jenkins sends the response back to the sonarqube server.
When the Static Code Analysis passed we can look into our SonarQube server for the analysis of our Code.
Using the “Upload Jar to Nexus” stages, we push our artifacts to the Nexus server.
We can get our release as well as a snapshot in the Nexus server. At first, we tested the hard-coded release and send it to the Nexus server.
Upload to compressed jar file for our repository.
We then automate our release version by writing some functions:
def readPomVersion = readMavenPom file: 'pom.xml'
We again send our artifacts to the Nexus server but this time we use the function to add our release.
Our next steps will be to build the docker image and push it to the docker hub. In this stage, we will build the multi-stage Docker images and push it to the Docker hub.
We then can check the docker hub for the image.
This way, we complete the Continuous Integration of Java applications, building, and testing, SonarQube completes static code analysis and the latest image is created, and pushed to DockerHub with the latest image.
Continuous Delivery/Deployment Part(Using GitOps Tool Argo CD)
ArgoCD is utilized in Kubernetes to establish a completely automated continuous delivery pipeline for the configuration of Kubernetes. This tool follows the GitOps approach and operates in a declarative manner to deliver Kubernetes deployments seamlessly.
As the next part, we should implement the CD part where we use ArgoCd to deploy our app images in Kubernetes.
We can use our local terminal and with the help of Minikube, we can achieve the required process.
Install Argo CD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
This will create a new namespace, argocd, where Argo CD services and application resources will live.
Check whether our namespace is created or not
kubectl get namespace
Check pods list
kubectl get pods -n argocd
kubectl get svc -n argocd
NodePort services are useful for exposing pods to external traffic where clients have network access to the Kubernetes nodes.
kubectl edit svc argocd-server -n argocd
And change from ClusterIP to NodePort. Save it.
minikube service list -n argocd
minikube service argocd-server -n argocd
Password for Argo CD
Find out password for Argo CD, so that, we can access Argo CD web interface.
kubectl get secret -n argocd
kubectl edit secret argocd-initial-admin-secret -n argocd
Copy admin.password
Now decrypted the password with this command:
echo <admin.password> | base64 - -decode
Finally logged on Argocd
After logging in to ArgoCD We create the new app and enter the required field as necessary. And it will take the deployment file and deploy the images in Kubernetes.
kubectl get deploy
In This way, we deploy our App in Kubernetes following the CI/CD practices.
Argo CD is a Kubernetes controller, responsible for continuously monitoring all running applications and comparing their live state to the desired state specified in the Git repository.
Conclusion:
In conclusion, implementing a comprehensive CI/CD pipeline utilizing SonarQube, Maven, Nexus, Docker, and the GitOps approach with Argo CD facilitated efficient software development. Jenkins played a pivotal role in orchestrating the Continuous Integration (CI) phase, while Argo CD seamlessly handled the Continuous Delivery (CD) aspect, resulting in the reliable deployment of the application onto Kubernetes.
Thank you for reading this blog. If you found this blog helpful, please like, share, and follow me for more blog posts like this in the future.
— Happy Learning !!!