Implementing a Secure Multi‑Language DevSecOps CI/CD Pipeline with Jenkins
This article details how to build a comprehensive DevSecOps CI/CD pipeline using Jenkins that integrates source control, SonarCloud, Snyk, Docker, Trivy, Kubernetes, and ZAP to automate building, testing, scanning, and deploying multi‑language applications securely and efficiently.
Introduction
In fast‑paced software development, a robust CI/CD pipeline is essential. This guide walks through creating a DevSecOps pipeline that combines Git, SonarCloud, Snyk, multi‑language build automation, Docker, Aqua Trivy, Kubernetes, and ZAP Proxy to achieve seamless automation, security, and deployment.
Pipeline Configuration
Configure the Jenkins pipeline job to use a Jenkinsfile from SCM. Choose the SCM source, branch, and script path, then save the configuration.
Stage 1 – Clean Workspace
The workspace is cleaned to remove previous artifacts before checking out fresh code.
Stage 2 – Git Checkout
Multiple source control systems (GitHub, GitLab, AWS CodeCommit, Bitbucket, SVN, TFS) can be used; the pipeline checks out the repository using provided credentials.
Stage 3 – SonarCloud
SonarCloud performs SAST code‑quality analysis. Integrate it by adding a personal access token and configuring the Sonar scanner tool in the pipeline.
Stage 4 – Snyk Security Scan
Snyk scans for known vulnerabilities. Provide the Snyk installation name and token, then run the scan with appropriate arguments.
Stage 5 – Java Detection
A Groovy function detects the Java version used by the project and selects the matching JDK tool for subsequent steps.
// Define the detectJavaVersion function outside of the pipeline block
def detectJavaVersion() {
def javaVersionOutput = sh(script: 'java -version 2>&1', returnStatus: false, returnStdout: true).trim()
def javaVersionMatch = javaVersionOutput =~ /openjdk version "(\d+\.\d+)/
if (javaVersionMatch) {
def javaVersion = javaVersionMatch[0][1]
if (javaVersion.startsWith("1.8")) {
return '8'
} else if (javaVersion.startsWith("11")) {
return '11'
} else if (javaVersion.startsWith("17")) {
return '17'
} else {
error("Unsupported Java version detected: ${javaVersion}")
}
} else {
error("Java version information not found in output.")
}
}
pipeline {
agent any
environment {
SONARCLOUD = 'Sonarcloud'
SNYK_INSTALLATION = 'snyk@latest'
SNYK_TOKEN = 'Snyk'
DOCKER_REGISTRY_CREDENTIALS = 'Docker_Server'
DOCKER_IMAGE = 'ganesharavind124/anacart:latest'
DOCKER_TOOL = 'Docker'
DOCKER_URL = 'https://index.docker.io/v1/'
KUBE_CONFIG = 'kubernetes'
}
stages {
// ... (remaining stages omitted for brevity)
}
}Stage 6 – Multi‑Language Build and Test
Detects the language of the source code (Java, Node.js, Python, .NET, PHP, iOS, Android, Ruby, Rust, etc.) and runs the appropriate build and test commands (Maven, npm, pip, dotnet, cargo, etc.).
Stage 7 – Docker Build and Push
If a Dockerfile exists, the pipeline builds the image and pushes it to the configured registry (Docker Hub, ECR, GCR, Harbor, etc.).
Stage 8 – Aqua Trivy Image Scan
Trivy scans the built Docker image for known vulnerabilities, using a local installation or a Docker‑based execution.
Stage 9 – Kubernetes Deployment
The pipeline deploys the image to a Kubernetes cluster using a deployment YAML file, handling namespace and kubeconfig credentials.
Stage 10 – ZAP DAST Test
ZAP Proxy performs dynamic application security testing against the deployed service URL, generating a report.
Running the Pipeline
Create a Jenkins pipeline job, select the SCM‑based Jenkinsfile, ensure all credentials and environment variables are set, then trigger a build. The console output shows successful execution of each stage, including SonarCloud analysis, Snyk scan, Docker image creation, Trivy report, Kubernetes deployment, and ZAP results.
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.