Jenkinsfile & Pipeline Execution

Goal: To explain the complete Jenkins pipeline script, stage by stage, and show how to configure the Jenkins job to run it.

This Jenkinsfile is the heart of the CI/CD process. It defines every step, from checkout to deployment, and is designed to run inside the custom Docker agent we defined in Jenkins Agent Dockerfile.

1. Jenkins Job Configuration

First, you must create the "Pipeline" job in Jenkins and configure its parameters.

  1. From the Jenkins Dashboard, click on New Item.
  2. Enter a name (e.g., EGL-GKE-Deployment), select Pipeline, and click OK.
  3. On the configuration page, go to the General tab.
  4. Check the box This project is parameterized.
  5. Add the following parameters. These allow you to run the same pipeline for different branches, versions, and applications:
Parameter Type Name Default Value Description
String Parameter GIT_REPO_URL https://github.com/your-repo.git The Git repo contains your Dockerfile, .yaml files, and .war file.
String Parameter GIT_BRANCH main The Git branch to check out.
String Parameter WAR_FILE_PATH target/app.war The path inside the Git repo to your compiled .war file.
String Parameter IMAGE_TAG latest The version tag to apply to your Docker image (e.g., 1.0.0, v2).
Password Parameter TOMCAT_PASSWORD The password for the Tomcat manager (will be passed to Dockerfile).

2. The Complete Jenkinsfile

Go to the Pipeline tab at the bottom of the job configuration page, select Pipeline script from the dropdown, and paste the following script.
Groovy
pipeline {
    // 1. DEFINE THE DYNAMIC DOCKER AGENT
    // This agent block tells Jenkins to start a new container
    // from your custom image (defined in Jenkins Agent Dockerfile) for this job.
    agent {
        docker {
            image 'gcp-jenkins-agent:latest'
            label 'gcp-build-agent'
        }
    }

// 2. DEFINE ENVIRONMENT VARIABLES
// These are static variables from your cloud setup (Required Cloud Environment & Credentials)
    environment {
        PROJECT_ID     = 'hclsw-gcp-rbd'
        CLUSTER_NAME   = 'kube-cluster'
        LOCATION       = 'us-central1'
 CREDENTIALS_ID = 'hclsw-service_Account' // ID of the credential from Jenkins Platform Setup (Prerequisites)
IMAGE_REPO     = 'us-central1-docker.pkg.dev/hclsw-gcp-rbd/hcl-rbd2/hcl-rbd2'
    }
    
    // 3. DEFINE PARAMETERS
    // These are the user-provided inputs from section 1
    parameters {
string(name: 'GIT_REPO_URL', defaultValue: 'https_github.com_your-repo.git', description: 'Git repo URL')
        string(name: 'GIT_BRANCH', defaultValue: 'main', description: 'Git branch to build')
string(name: 'WAR_FILE_PATH', defaultValue: 'target/app.war', description: 'Path to the .war file in the repo')
 string(name: 'IMAGE_TAG', defaultValue: 'latest', description: 'Docker image tag')
 password(name: 'TOMCAT_PASSWORD', description: 'Password for the Tomcat manager')
    }

    // 4. DEFINE PIPELINE STAGES
    stages {
        
        stage('Checkout SCM') {
            steps {
          cleanWs() // Clean the workspace from previous builds
echo "Checking out ${params.GIT_BRANCH} from ${params.GIT_REPO_URL}"
                // Clone the repo which contains:
                // 1. Application Dockerfile (Defining the Application Container (Dockerfile))
                // 2. K8s Manifests (Defining the Deployment Target (Kubernetes Manifests))
                // 3. The .war file
 git branch: params.GIT_BRANCH, url: params.GIT_REPO_URL
            }
        }

        stage('Set Dynamic Image Name') {
            steps {
                script {
 // Combine the repo URL and tag to create the full image name
env.IMAGE_NAME = "${env.IMAGE_REPO}:${params.IMAGE_TAG}"
                    echo "IMAGE_NAME set to: ${env.IMAGE_NAME}"
                }
            }
        }

        stage('Authenticate & Configure Docker') {
            steps {
 // Use the 'Secret file' credential from ChapJenkins Platform Setup (Prerequisites)
 withCredentials([file(credentialsId: env.CREDENTIALS_ID, variable: 'SERVICE_ACCOUNT_JSON')]) {
 sh """
 echo "Activating GCP Service Account..."
gcloud auth activate-service-account --key-file="\$SERVICE_ACCOUNT_JSON" --project="${env.PROJECT_ID}"
                        
  echo "Configuring Docker to authenticate with Artifact Registry..."
 gcloud auth configure-docker ${env.LOCATION}-docker.pkg.dev --quiet
                    """
                }
            }
        }

 stage('Build & Push Docker Image') {
   steps {
 // This 'docker build' command is executed by our agent container,
 // but it controls the *host's* Docker engine via the mounted socket.
  sh """
  echo "Building image: ${env.IMAGE_NAME}"
                    docker build \
                      --build-arg WARFILE='${params.WAR_FILE_PATH}' \
                      --build-arg TOMCAT_USER='tomcat' \
                      --build-arg TOMCAT_PASSWORD='${params.TOMCAT_PASSWORD}' \
                      -t "${env.IMAGE_NAME}" .
                      
                    echo "Pushing image: ${env.IMAGE_NAME}"
                    docker push "${env.IMAGE_NAME}"
                """
            }
        }

        stage('Deploy to GKE') {
            steps {
    // Use credentials again to get cluster access
     withCredentials([file(credentialsId: env.CREDENTIALS_ID, variable: 'SERVICE_ACCOUNT_JSON')]) {
                    sh """
                    export GOOGLE_APPLICATION_CREDENTIALS="\$SERVICE_ACCOUNT_JSON"
                        
  echo "Authenticating kubectl to GKE cluster: ${env.CLUSTER_NAME}"
  gcloud container clusters get-credentials ${env.CLUSTER_NAME} --zone ${env.LOCATION} --project ${env.PROJECT_ID}
                        
 echo "Replacing IMAGE_NAME placeholder in Deployment.yaml"
 # Use a different separator (like |) in case IMAGE_NAME contains slashes
  sed -i.bak "s|IMAGE_NAME|${env.IMAGE_NAME}|g" Deployment.yaml
                        
             echo "Applying Kubernetes manifests..."
               kubectl apply -f Deployment.yaml
               kubectl apply -f service.yaml
               kubectl apply -f ingress.yaml
                    """
                }
            }
        }
    }
    
    // 5. POST-BUILD ACTIONS
    post {
        success { echo "Pipeline completed successfully." }
        failure { echo "Pipeline failed — check logs." }
    }
}


3. Pipeline Stage-by-Stage Explanation

  • agent { docker { ... } } This block tells Jenkins not to use a standard agent. Instead, it starts a new Docker container from your gcp-jenkins-agent:latest image (from Jenkins Agent Dockerfile) and runs all steps inside it. The args line mounts the host's Docker socket, allowing this agent to build and push images.
  • environment { ... } These are static variables that define your target environment. They are sourced from the GCP resources set up in Required Cloud Environment & Credentials.
  • parameters { ... } These are the user-friendly inputs you just configured in the Jenkins UI. They make the pipeline reusable.
  • stage('Checkout SCM') This stage clones your Git repository, which contains all the necessary files: your application Dockerfile (Defining the Application Container (Dockerfile)), your Kubernetes manifests (Defining the Deployment Target (Kubernetes Manifests)), and your application's .war file.
  • stage('Set Dynamic Image Name') This is a simple helper stage that combines the IMAGE_REPO (e.g., .../hcl-rbd2) with the user's IMAGE_TAG (e.g., 1.0.1) to create the full, unique image name: .../hcl-rbd2:1.0.1.
  • stage('Authenticate & Configure Docker') This is the first critical authentication step. It uses the withCredentials helper (from the plugin in Jenkins Platform Setup (Prerequisites)) to load your SERVICE_ACCOUNT_JSON (from Required Cloud Environment & Credentials). It then uses gcloud to log in and configure the Docker CLI to push to Google Artifact Registry.
  • stage('Build & Push Docker Image') This stage runs the docker build command. It uses --build-arg to securely pass the WAR_FILE_PATH and TOMCAT_PASSWORD (from the Jenkins parameters) into your application Dockerfile (from Defining the Application Container (Dockerfile)). After a successful build, it pushes the tagged image to Artifact Registry.
  • stage('Deploy to GKE') This is the final deployment.
    1. It uses gcloud container clusters get-credentials to configure kubectl to point to your GKE cluster.
    2. It runs sed -i.bak ... to find the IMAGE_NAME placeholder in your Deployment.yaml (from Defining the Deployment Target (Kubernetes Manifests)) and replace it with the new image name (e.g., .../hcl-rbd2:1.0.1).
    3. It runs kubectl apply on all three manifest files. Kubernetes receives these, sees the new image in the Deployment, and automatically begins a rolling update of your application.
  • post { ... } This block runs after the pipeline finishes. It provides a simple success or failure message in the Jenkins log.