Trivy EP17 | Production-Grade Trivy in Jenkins | Automated DevSecOps Pipeline (Docker + SBOM)
This chapter covers the end-to-end integration of Trivy security scanning within a Jenkins CI/CD pipeline on an AWS EC2 instance. We build a complete DevSecOps workflow that automatically pulls a Python application source code, builds a Docker container, executes Trivy vulnerability scans, and generates multi-format compliance reports including JSON, HTML, and Software Bill of Materials (SBOM) artifacts.
1. Why Do We Need Automated DevSecOps Scanning in CI/CD?
In modern software development, security cannot be an afterthought handled manually before production releases. Running security scans directly inside automated pipelines ensures continuous compliance and shifts security left.
- Eliminating Manual Bottlenecks: Manual vulnerability assessments slow down delivery velocity and are prone to human oversight.
- Immediate Feedback Loops: Developers receive immediate feedback on vulnerabilities introduced in container images or application dependencies before code reaches staging or production environments.
- Standardized Compliance Artifacts: Regulators and enterprise security teams increasingly demand standardized artifacts such as Software Bill of Materials (SBOMs) and human-readable vulnerability reports for every build.
2. Core Architecture & Infrastructure Setup
To implement this production-grade pipeline, we provision a dedicated AWS EC2 instance running Ubuntu. This server hosts all necessary orchestration and containerization runtimes.
AWS EC2 Instance Specification
- AMI: Ubuntu (Quick Start)
- Instance Type:
M7i-flex.large(8 GB Memory) - Storage: 20 GB GP3 EBS Root Volume
- Security Group Rules:
SSH (Port 22): Restricted administrative accessHTTP (Port 80): Web trafficCustom TCP (Port 8080): Jenkins web dashboard access
3. Step-by-Step Server Provisioning & Tool Installation
Before configuring Jenkins pipelines, the underlying operating system must be prepared with Java, Jenkins, Docker, and Trivy.
Step 3.1: Connecting to the EC2 Instance
After launching the instance and downloading the key pair (Trivy-demo.pem), fix the private key file permissions on your local terminal before initiating an SSH connection:
# Restrict private key permissions
chmod 400 trivy-demo.pem
# Connect via SSH
ssh -i "trivy-demo.pem" ubuntu@<EC2-PUBLIC-IP>
Step 3.2: Installing Jenkins & Java Runtime Environment (JRE)
Jenkins requires Java to execute. We install the Long Term Support (LTS) release of Jenkins following official repository procedures:
# Update package index and install Java (JRE)
sudo apt update
sudo apt install fontconfig openjdk-17-jre -y
# Add Jenkins repository key and source list
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee \
/usr/share/keyrings/jenkins-keyring.asc > /dev/null
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 update
sudo apt install jenkins -y
# Start and enable Jenkins service
sudo systemctl enable jenkins
sudo systemctl start jenkins
Step 3.3: Installing Docker Engine
Docker is required to build application container images that Trivy will inspect.
# Remove conflicting packages if any
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
sudo apt-get remove $pkg
done
# Set up Docker's apt repository
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg -y
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu "$(. /etc/os-release &&ungsver)" \
"$(e.g., stable)" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker Engine and Containerd
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
# Verify Docker installation
sudo systemctl status docker
Step 3.4: Installing Trivy CLI
Install Aqua Security's Trivy vulnerability scanner on the host system:
# Add Trivy repository key and repository
sudo apt-get install wget apt-transport-https gnupg lsb-release -y
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/trivy.list
# Update and install Trivy
sudo apt-get update
sudo apt-get install trivy -y
# Verify Trivy version
trivy --version
4. Resolving Jenkins & Docker Permission Pitfalls
Industry Reality & Debugging Mindset: By default, the
jenkinssystem user cannot execute Docker commands because it lacks membership in thedockerUnix group. When Jenkins attempts to rundocker buildor interact with the local Docker daemon, builds fail with apermission denied while trying to connect to the Docker daemon socketerror.
To resolve this production roadblock, add the jenkins user to the docker group and restart both services:
# Add jenkins user to the docker group
sudo usermod -aG docker jenkins
# Restart Jenkins and Docker services to apply group changes
sudo systemctl restart jenkins
sudo systemctl restart docker
5. Jenkins Initial Unlock & Dashboard Configuration
- Access Jenkins: Open your browser and navigate to
http://<EC2-PUBLIC-IP>:8080. - Retrieve Administrator Password: Run the following command on your EC2 terminal to read the initial admin password generated during installation:
BASH
sudo cat /var/lib/jenkins/secrets/initialAdminPassword - Complete Setup Wizard:
- Paste the secret password into the Jenkins web prompt.
- Select Install suggested plugins.
- Create your first administrative user (username, password, full name, and email).
- Save and finalize the Jenkins setup.
6. Anatomy of the Python Target Application & Dockerfile
The repository being automated contains a lightweight Python application that runs on port 5000 and outputs a custom greeting string, accompanied by a multi-stage or standard Dockerfile.
Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]
requirements.txt
Flask==2.2.3
Werkzeug==2.2.3
7. Creating and Configuring the Jenkins Pipeline Job
We now configure a pipeline job in Jenkins to automate building the image and generating security reports via Trivy.
- Go to the Jenkins Dashboard and click New Item.
- Enter the item name:
trivy-report-automation. - Select Pipeline and click OK.
- Scroll down to the Pipeline section:
- Definition: Select
Pipeline script from SCM. - SCM: Select
Git. - Repository URL: Provide your Git repository URL containing the sample project.
- Branch Specifier:
*/main. - Script Path:
Jenkinsfile(or the specific path inside your monolithic repository, e.g.,sub-repo-9/Jenkinsfile).
- Definition: Select
- Click Save.
8. Complete Jenkinsfile Pipeline Definition
The pipeline orchestrates checking out the source code, building the Docker container image, executing Trivy scans across multiple formats, and persisting the resulting artifacts.
pipeline {
agent any
environment {
IMAGE_NAME = "python-app-demo"
IMAGE_TAG = "v1.${env.BUILD_NUMBER}"
}
stages {
stage('Checkout Code') {
steps {
checkout scm
}
}
stage('Build Docker Image') {
steps {
script {
echo "Building Docker image: ${IMAGE_NAME}:${IMAGE_TAG}"
sh "docker build -t ${IMAGE_NAME}:${IMAGE_TAG} ."
}
}
}
stage('Trivy Security Scans') {
steps {
script {
echo "Running Trivy Vulnerability and Compliance Scans..."
// Create artifacts directory
sh "mkdir -p trivy-reports"
// 1. JSON Report
sh "trivy image --format json -o trivy-reports/report.json ${IMAGE_NAME}:${IMAGE_TAG}"
// 2. HTML Report
sh "trivy image --format template --template '@contrib/html.tpl' -o trivy-reports/report.html ${IMAGE_NAME}:${IMAGE_TAG}"
// 3. SBOM (Software Bill of Materials) Report in CycloneDX format
sh "trivy image --format cyclonedx -o trivy-reports/sbom.json ${IMAGE_NAME}:${IMAGE_TAG}"
}
}
}
}
post {
always {
echo "Archiving generated security artifacts..."
archiveArtifacts artifacts: 'trivy-reports/*', fingerprint: true
}
success {
echo "Pipeline completed successfully with all security reports generated!"
}
failure {
echo "Pipeline failed during build or security scanning stages."
}
}
}
9. Pipeline Execution & Artifact Verification
Trigger a manual build by clicking Build Now on the Jenkins project dashboard.
Step-by-Step Execution Flow
Viewing and Downloading Generated Artifacts
Once the build completes successfully:
- Click on the specific build number (e.g.,
#2) in Jenkins. - Navigate to the Artifacts section on the left sidebar.
- You will see the
trivy-reports/directory containing:report.json: Machine-readable vulnerability data for ingestion into SIEM or dashboard tools.report.html: Beautiful, human-readable HTML report viewable in any browser.sbom.json: Industry-standard CycloneDX Software Bill of Materials detailing every library, version, and license packed inside the container image.
10. Summary and Key Takeaways
- Automated DevSecOps Integration: Embedding Trivy directly into Jenkins pipelines shifts security left, ensuring every code push and container build is automatically scanned.
- Prerequisite Stack: Running containerized builds in Jenkins requires proper orchestration of Java, Jenkins, Docker, and the Trivy CLI on an underlying Linux host (Ubuntu).
- Resolving Docker Daemon Permissions: Always ensure the
jenkinssystem user is added to thedockerUnix group (sudo usermod -aG docker jenkins) to prevent permission denied errors when interacting with/var/run/docker.sock. - Multi-Format Reporting: A single Trivy scanning run can output multiple formats simultaneously by specifying flags like
--format json,--format templatewith HTML templates, and--format cyclonedxfor SBOMs. - Compliance & Auditing: SBOM generation (
sbom.json) provides complete transparency into application software supply chains, meeting enterprise and regulatory compliance demands. - Artifact Archiving: Using Jenkins post-build steps (
archiveArtifacts) guarantees that security reports are safely preserved and easily accessible for security auditors and developers.