This project sets up a Jenkins pipeline to automate the CI/CD process for an application. The pipeline includes stages for testing the application, building a Docker image, pushing the image to Docker Hub, and deploying the application on OpenShift. The pipeline leverages an EC2 instance as a Jenkins slave and uses a shared library hosted on GitHub for reusable pipeline code.
-
Jenkins master configured with the following plugins:
- Git
- Pipeline
- Docker
- OpenShift
-
An EC2 instance configured as a Jenkins slave.
-
OpenJDK, Docker and oc cli installed and configured on the EC2 slave using Ansible Playbook.
-
A GitHub repository containing the shared library.
-
An OpenShift cluster and CLI configured.
- Test: Run unit tests to ensure the codebase is stable.
- Build Docker Image: Build a Docker image for the application.
- Edit new image in deployment.yaml file Edit new image to push on docker hub
- Push Docker Image: Push the Docker image to Docker Hub.
- Deploy on OpenShift: Deploy the application on an OpenShift cluster.
-
Launch an EC2 instance.
-
Configure the EC2 instance as a Jenkins build agent.
-
Install OpenJDK, Docker and oc cli on the EC2 instance Using Ansible Playbook.
-
Create a shared library in a GitHub repository.
-
Define common pipeline steps (e.g., test, build, push, deploy) in the shared library As a groovy function.
#!/usr/bin/env groovy
def call() {
echo "Running Unit Test..."
sh './gradlew clean test'
}
#!usr/bin/env groovy
def call(String dockerHubCredentialsID, String imageName) {
// Log in to DockerHub
withCredentials([usernamePassword(credentialsId: "${dockerHubCredentialsID}", usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
sh "docker login -u ${USERNAME} -p ${PASSWORD}"
}
// Build and push Docker image
echo "Building and Pushing Docker image..."
sh "docker build -t ${imageName}:${BUILD_NUMBER} ."
sh "docker push ${imageName}:${BUILD_NUMBER}"
}
#!/usr/bin/env groovy
def call(String imageName) {
// Edit deployment.yml with new Docker Hub image
sh "sed -i 's|image:.*|image: ${imageName}:${BUILD_NUMBER}|g' deployment.yml"
}
#!/usr/bin/env groovy
def call(String openshiftCredentialsID, String nameSpace, String clusterUrl) {
// Login to OpenShift using the service account token
withCredentials([string(credentialsId: openshiftCredentialsID, variable: 'OC_TOKEN')]) {
sh "oc login --token=$OC_TOKEN --server=$clusterUrl --insecure-skip-tls-verify"
}
// Apply the updated deployment.yaml to the OpenShift cluster
sh "oc apply -f . --namespace=${nameSpace}"
}
-
Create The github, dockerhub, oc-token As.
-
Define common pipeline steps (e.g., test, build, push, deploy) in the shared library.
-
And oc-token in Jenkins As
-
Go to Jenkins dashboard and create a new pipeline job and write.
-
Configure the job to use the EC2 slave as the build agent.
pipeline { agent { // Specifies a label to select an available agent node { label 'jenkins-slave' } }
-
Configure the pipeline script to use the shared library by adding the following line in the first line in your Jenkinsfile Pipeline.
@Library('Jenkins-Shared-Library')_
-
The final Jenkinsfile or pipeline contents
@Library('Jenkins-Shared-Library')_
pipeline {
agent {
// Specifies a label to select an available agent
node {
label 'jenkins-slave'
}
}
environment {
dockerHubCredentialsID = 'DockerHub' // DockerHub credentials ID.
imageName = 'alikhames/java-app' // DockerHub repo/image name.
openshiftCredentialsID = 'openshift' // KubeConfig credentials ID.
nameSpace = 'alikhames'
clusterUrl = 'https://api.ocp-training.ivolve-test.com:6443'
}
stages {
stage('Run Unit Test') {
steps {
script {
runUnitTests
}
}
}
stage('Build and Push Docker Image') {
steps {
script {
buildandPushDockerImage("${dockerHubCredentialsID}", "${imageName}")
}
}
}
stage('Edit new image in deployment.yaml file') {
steps {
script {
dir('oc') {
editNewImage("${imageName}")
}
}
}
}
stage('Deploy on OpenShift Cluster') {
steps {
script {
dir('oc') {
deployOnOc("${openshiftCredentialsID}", "${nameSpace}", "${clusterUrl}")
}
}
}
}
}
post {
success {
echo "${JOB_NAME}-${BUILD_NUMBER} pipeline succeeded"
}
failure {
echo "${JOB_NAME}-${BUILD_NUMBER} pipeline failed"
}
}
}
oc get route route-name -n namespace