How to Build a CI/CD Pipeline for Java Spring Boot with Jenkins, Kubernetes, and AWS EC2


As a DevOps enthusiast, I constantly explore new ways to automate and streamline the development lifecycle. Recently, I worked on an exciting project where I successfully created a CI/CD pipeline for a Java Spring Boot application using tools like Jenkins, Kubernetes, and AWS EC2. This blog will walk you through the entire process, from setting up the pipeline to deploying the application, with a focus on industry best practices.
GitHub repository.
A big thank you to Aditya from DevOps Shack for his detailed YouTube tutorial that guided me through the setup process.
Project Overview
The application I worked on is a Board Game Database Web Application where users can view, add, and review board games. The key features include:
Authentication and Authorization: Users can log in to add and review board games. Different roles, like users and managers, have varying levels of access.
CRUD Operations: Users can perform create, read, update, and delete operations on the board games and reviews.
Full-Stack Features: The front end is built using Thymeleaf with Spring Boot powering the back end. The application is deployed on AWS EC2.
The main challenge was to create an end-to-end CI/CD pipeline that automates everything from code push to deployment. Below is a breakdown of how I implemented this project.
Key Technologies Used
Jenkins for CI/CD automation
Docker for containerizing the application
Kubernetes for orchestrating the containers in a production environment
AWS EC2 for cloud hosting
SonarQube for code quality checks
Trivy for security scanning
Prometheus and Grafana for monitoring and observability
Maven for project build management
Java Spring Boot for the back-end, with Thymeleaf for the front-end
Setting up Kubernetes cluster
I have written a detailed blog on creating a Kubernetes cluster on AWS EC2 using the Kubeadm.
Jenkins Pipeline Breakdown
I have created the AWS EC2 instance of t2.large size and 20GB EBS storage.
Run the below commands to install Jenkins on the EC2 instance:
sudo apt install openjdk-17-jre-headless
sudo apt update
sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \
https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]" \
https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
/etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins
Install a few plugins on the Jenkins server:
Eclipse Temurin Installer
Config file provider
Pipeline Maven Integration
SonarQube scanner
Docker and Docker pipeline
Kubernetes Client API, Kubernetes Credentials, Kubernetes, and Kubernetes CLI
Now, create a Jenkins Pipeline job:
pipeline {
agent any
tools {
jdk 'jdk17'
maven 'maven3'
}
environment {
SCANNER_HOME = tool 'sonar-scanner'
}
stages {
stage('Git Checkout') {
steps {
git branch: 'main', credentialsId: 'git-cred', url: 'https://github.com/your-repo/project-board-game.git'
}
}
stage('Compile') {
steps {
sh "mvn compile"
}
}
stage('Test') {
steps {
sh "mvn test"
}
}
stage('File System Scanning') {
steps {
sh "trivy fs --format table -o trivy-fs-report.html ."
}
}
stage('SonarQube Analysis') {
steps {
withSonarQubeEnv('sonar-server') {
sh ''' $SCANNER_HOME/bin/sonar-scanner -Dsonar.projectName=board-game -Dsonar.projectKey=board-game \
-Dsonar.java.binaries=.'''
}
}
}
stage("Quality Gate") {
steps {
script {
waitForQualityGate abortPipeline: false, credentialsId: 'sonar-token'
}
}
}
stage("Build") {
steps {
sh "mvn package"
}
}
stage("Publish Artifacts to Nexus") {
steps {
withMaven(globalMavenSettingsConfig: 'global-maven-settings', jdk: 'jdk17', maven: 'maven3') {
sh "mvn deploy"
}
}
}
stage("Build and Tag Docker Image") {
steps {
withDockerRegistry(credentialsId: 'docker-cred', toolName: 'docker') {
sh "docker build -t your-docker-image:latest ."
}
}
}
stage("Docker Image Scan") {
steps {
sh "trivy image --format table -o trivy-image-report.html your-docker-image:latest"
}
}
stage("Push Docker Image") {
steps {
withDockerRegistry(credentialsId: 'docker-cred', toolName: 'docker') {
sh "docker push your-docker-image:latest"
}
}
}
stage("Deploy to Kubernetes") {
steps {
withKubeConfig(credentialsId: 'k8s-cred', serverUrl: 'https://your-k8s-server-url') {
sh "kubectl apply -f k8s-deployment.yaml"
}
}
}
stage("Verify Deployment") {
steps {
withKubeConfig(credentialsId: 'k8s-cred', serverUrl: 'https://your-k8s-server-url') {
sh "kubectl get pods"
sh "kubectl get svc"
}
}
}
}
post {
always {
script {
def jobName = env.JOB_NAME
def buildNumber = env.BUILD_NUMBER
def pipelineStatus = currentBuild.result ?: 'UNKNOWN'
def body = "<html><body><h2>${jobName} - Build ${buildNumber}</h2><p>Pipeline Status: ${pipelineStatus}</p></body></html>"
emailext(subject: "${jobName} - Build ${buildNumber} - ${pipelineStatus}", body: body, to: 'your-email@example.com')
}
}
}
}
Jenkins Pipeline Breakdown:
Step 1: Git Checkout – Fetching the code from GitHub
Step 2: Compilation & Testing – Using Maven & JUnit
Step 3: Security Scans
Trivy FS (for file system scanning)
SonarQube (for code quality analysis)
Trivy Image (for Docker image scanning)
Step 4: Artifact Management – Publishing to Nexus
Step 5: Dockerization & Push – Building & pushing Docker image
Step 6: Kubernetes Deployment – Applying manifests
Step 7: Sending email - Send an email to the developer regarding the result of Pipeline
Step 8: Verification – Checking running services
Security was a significant concern, so I integrated Trivy for the file system and Docker image scanning. Additionally, I used SonarQube to check continuous code quality.
Monitoring & Observability Setup
For monitoring, I configured Prometheus and Grafana to observe the performance of the application and the Kubernetes cluster. Blackbox Exporter was used to monitor the application uptime, while Node Exporter tracked the system performance of the Jenkins server.
Challenges & Lessons Learned
Kubernetes Setup Issues: Fixed networking with proper CNI configuration.
RBAC Misconfigurations: The least privilege access was implemented for Jenkins.
Pipeline Failures: Debugged Maven builds and optimized Dockerfile.
Monitoring Gaps: Configured proper scraping in Prometheus.
What's Next?
The following steps will be to further enhance the application by:
Implementing CI/CD for multiple environments (development, staging, production)
Automating infrastructure provisioning using Terraform
Adding more advanced monitoring and alerting features
#DevOps #CI_CD #Jenkins #Kubernetes #AWS #Docker #SpringBoot #Monitoring #Security #CloudComputing #Automation #DevOpsCommunity
Subscribe to my newsletter
Read articles from Vishukumar Patel directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Vishukumar Patel
Vishukumar Patel
Hi there! I’m a DevOps enthusiast, certified in AWS, and passionate about crafting innovative cloud solutions. From designing scalable CI/CD pipelines to deploying microservices on cloud platforms, I’ve immersed myself in transforming ideas into impactful technologies.