Comprehensive Guide to Setting Up a CI/CD Pipeline with Jenkins, Docker, SonarQube, and ArgoCD on AWS and Kubernetes
This step‑by‑step tutorial explains how to configure a full CI/CD pipeline using Jenkins, Maven, Docker, SonarQube, Helm, and ArgoCD on an AWS EC2 instance with Kubernetes, covering version‑control setup, instance provisioning, credential management, pipeline scripting, and automated deployment.
Introduction
Continuous Integration and Continuous Delivery (CI/CD) are essential in modern software development for automating code integration and reliable application delivery. Jenkins is a leading tool for building CI/CD pipelines due to its flexibility and extensive plugin ecosystem.
This guide walks through the complete setup of a CI/CD pipeline using Jenkins, covering configuration, integration with version control, and orchestration of build, test, and deployment steps to enhance software delivery processes.
Tools and Technologies Used
GitHub for version control
Maven for project management and build
SonarQube for code quality analysis
Docker for containerization
Jenkins for continuous integration
ArgoCD and Helm for Kubernetes deployment management
Kubernetes for container orchestration
Configure Version Control System
To set up a Java application pipeline, first configure Git:
Create a private Git repository on your preferred platform (GitHub, GitLab, etc.).
Generate a personal access token with repo permissions and store it securely.
Clone the repository locally using:
git cloneCreate EC2 Instance
Although this step can be automated with Terraform, we perform it manually for simplicity.
Log in to the AWS Management Console.
Navigate to the EC2 dashboard.
Launch an instance (e.g., t2.large ) with a suitable AMI, configure security groups to allow ports 22, 8080, and 9000, add tags, a key pair, and storage.
Review the configuration and launch the instance.
Access Your Instance
After the instance initializes, connect via SSH using the downloaded .pem file (e.g., with MobaXterm on Windows).
Set Up Jenkins
Install Java (OpenJDK 11) on the server:
sudo apt update
sudo apt install openjdk-11-jdk
java -versionCreate an installation script for Jenkins:
vim install_jenkins.sh #!/bin/bash
# Download Jenkins GPG key
sudo wget -O /usr/share/keyrings/jenkins-keyring.asc https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
# Add Jenkins repository
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
# Update and install Jenkins
sudo apt-get update
sudo apt-get install jenkins -yMake the script executable and run it:
chmod +x install_jenkins.sh
./install_jenkins.shAdjust the firewall to allow inbound traffic on port 8080, then access the Jenkins UI at http:// :8080 using the initial admin password:
sudo cat /var/lib/jenkins/secrets/initialAdminPasswordInstall the recommended plugins, create an admin user, and configure the Jenkins URL.
Install Necessary Plugins
From “Manage Jenkins → Plugins”, install the “docker pipeline” and “SonarQube Scanner” plugins and restart Jenkins if required.
Configure SonarQube Server
Run SonarQube as a Docker container (Docker must be installed first). Create a Docker installation script:
vim install_docker.sh #!/bin/bash
sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo \"$VERSION_CODENAME\") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginMake it executable and run it, then pull and run SonarQube:
docker pull sonarqube
docker run -d --name sonarqube -p 9000:9000 sonarqubeSonarQube defaults to port 9000; ensure the security group permits inbound traffic on this port. The default credentials are admin/admin ; change them after the first login. Generate a SonarQube token and add it to Jenkins credentials as a secret text.
Configure System Authentication Credentials
Ensure all required credentials for Git, Docker Hub, and SonarQube are stored in Jenkins (e.g., as secret text or username/password credentials).
Jenkinsfile
The Jenkinsfile defines the pipeline stages using Groovy:
pipeline {
agent {
docker {
image 'abhishekf5/maven-abhishek-docker-agent:v1'
args '--user root -v /var/run/docker.sock:/var/run/docker.sock' // mount Docker socket
}
}
stages {
stage('Checkout') {
steps {
sh 'echo passed'
// git branch: 'main', url: 'https://github.com/...'
}
}
stage('Build and Test') {
steps {
sh 'ls -ltr'
sh 'cd spring-boot-app && mvn clean package'
}
}
stage('Static Code Analysis') {
environment {
SONAR_URL = "http://54.252.140.131:9000"
}
steps {
withCredentials([string(credentialsId: 'sonarqube', variable: 'SONAR_AUTH_TOKEN')]) {
sh 'cd spring-boot-app && mvn sonar:sonar -Dsonar.login=$SONAR_AUTH_TOKEN -Dsonar.host.url=${SONAR_URL}'
}
}
}
stage('Build and Push Docker Image') {
environment {
DOCKER_IMAGE = "ultimate-cicd:${BUILD_NUMBER}"
REGISTRY_CREDENTIALS = credentials('docker-cred')
}
steps {
script {
sh 'cd spring-boot-app && docker build -t ${DOCKER_IMAGE} .'
def dockerImage = docker.image("${DOCKER_IMAGE}")
docker.withRegistry('https://index.docker.io/v1/', "docker-cred") {
dockerImage.push()
}
}
}
}
stage('Update Deployment File') {
environment {
GIT_REPO_NAME = "jenkins-CICD"
GIT_USER_NAME = "wangoimwangi"
}
steps {
withCredentials([string(credentialsId: 'github', variable: 'GITHUB_TOKEN')]) {
sh '''
git config user.email "[email protected]"
git config user.name "Maria"
BUILD_NUMBER=${BUILD_NUMBER}
sed -i s/replaceImageTag/${BUILD_NUMBER}/g spring-boot-app-manifests/deployment.yml
git add spring-boot-app-manifests/deployment.yml
git commit -m "Update deployment image to version ${BUILD_NUMBER}"
git push https://${GITHUB_TOKEN}@github.com/${GIT_USER_NAME}/${GIT_REPO_NAME} HEAD:main
'''
}
}
}
}
}Trigger the pipeline with “Build Now” and monitor progress in the Jenkins dashboard.
Set Up ArgoCD
ArgoCD manages the continuous‑deployment part of the pipeline. Install Minikube, Kubectl, and the ArgoCD Operator, then apply a basic ArgoCD custom resource.
minikube start
# Install Operator Lifecycle Manager (OLM)
curl -sL https://github.com/operator-framework/operator-lifecycle-manager/releases/download/v0.27.0/install.sh | bash -s v0.27.0
# Install ArgoCD Operator
kubectl create -f https://operatorhub.io/install/argocd-operator.yaml
# Apply ArgoCD instance
cat <
argocd-basic.yml
apiVersion: argoproj.io/v1alpha1
kind: ArgoCD
metadata:
name: example-argocd
labels:
example: basic
spec: {}
EOF
kubectl apply -f argocd-basic.ymlExpose the ArgoCD server UI via NodePort and retrieve the admin password from the secret:
kubectl get svc
minikube service argocd-server --url
kubectl get secret
kubectl edit secret example-argocd-cluster
# The password is Base64‑encoded; decode it:
echo
| base64 -dLog in to the UI with username admin and the decoded password.
Deploy Applications with ArgoCD
In the ArgoCD UI, click “Create Application”, provide the application name, project, repository URL, path to manifests, target cluster URL, and namespace, then enable automatic sync. ArgoCD will continuously deploy the application to the Kubernetes cluster.
Conclusion
The project demonstrates how to integrate GitHub, Maven, SonarQube, Docker, Jenkins, ArgoCD, Helm, and Kubernetes into a CI/CD pipeline to improve development efficiency, delivery speed, and software quality.
DevOps Cloud Academy
Exploring industry DevOps practices and technical expertise.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.