Friday, September 25, 2026

How to Integrate SonarQube & Trivy with GitLab CI/CD | DevSecOps Pipeline with Quality Gate

In this tutorial, we will integrate Trivy and SonarQube with GitLab CI/CD to build a DevSecOps pipeline for a Java web application.

The pipeline will automatically:

Build → Trivy Security Scan → SonarQube Code Analysis + Quality Gate → Deploy to Tomcat

Pipeline Flow

Developer → GitLab → GitLab Runner → Maven Build → Trivy Scan → SonarQube Scan + Quality Gate

PASS → Deploy WAR → Tomcat → Java Web Application

FAIL → Pipeline Stops → No Deployment 

Prerequisites

Before starting this lab, make sure the following are ready:


What We Will Implement

We will perform the following steps:

  1. Generate a SonarQube authentication token.
  2. Configure SonarQube and Tomcat credentials as GitLab CI/CD variables.
  3. Create a .gitlab-ci.yml pipeline.
  4. Build the Java application using Maven.
  5. Scan the project using Trivy.
  6. Analyze the source code using SonarQube.
  7. Enforce the SonarQube Quality Gate.
  8. Deploy the WAR file to Tomcat only when all previous stages succeed.


What is Trivy?

Trivy is an open-source security scanner used in DevSecOps pipelines to identify vulnerabilities and other security issues. In this lab, we use Trivy to scan the application filesystem and dependencies for HIGH and CRITICAL vulnerabilities.

Trivy → Security/Vulnerability Scanning

SonarQube → Code Quality & Static Code Analysis

Step 1 – Create a SonarQube Token

Login to SonarQube.

Go to:

My Account → Security → Tokens


Enter a token name and generate an analysis token.

Copy the generated token.

Save the token securely. You will add it to GitLab as a CI/CD variable.


Step 2 – Configure GitLab CI/CD Variables

Go to your GitLab project:

Settings → CI/CD → Variables

Click Add variable.

Configure the following variables:

Variable Purpose
SONAR_HOST_URL SonarQube server URL
SONAR_TOKEN SonarQube authentication token
TOMCAT_HOST Tomcat hostname/IP and port
TOMCAT_USER Tomcat Manager username
TOMCAT_PASSWORD Tomcat Manager password

Do not hard-code passwords or tokens inside .gitlab-ci.yml.


Step 3 – Create the GitLab CI/CD Pipeline

Go to the GitLab repository containing your Java project.

Create a new file:

.gitlab-ci.yml

Our pipeline contains four stages:

stages:
  - build
  - security
  - sonar
  - deploy

The pipeline flow is:

Build → Trivy → SonarQube + Quality Gate → Deploy


Step 4 – Complete .gitlab-ci.yml

stages:
  - build
  - security
  - sonar
  - deploy


# -------------------------
# BUILD
# -------------------------

build_war:
  stage: build
  image: maven:3.8.6-eclipse-temurin-11

  script:
    - echo "Building WAR file using Maven"
    - mvn clean package -f MyWebApp/pom.xml
    - echo "Listing target directory"
    - ls -la MyWebApp/target

  artifacts:
    paths:
      - MyWebApp/target/*.war
    expire_in: 1 hour


# -------------------------
# TRIVY SECURITY SCAN
# -------------------------

trivy_scan:
  stage: security
  image:
    name: aquasec/trivy:latest
    entrypoint: [""]

  script:
    - echo "Running Trivy security scan"
    - trivy fs --severity HIGH,CRITICAL --exit-code 1 --no-progress .

  allow_failure: false


# -------------------------
# SONARQUBE CODE ANALYSIS
# -------------------------

sonarqube_scan:
  stage: sonar
  image: maven:3.9.6-eclipse-temurin-17

  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
    GIT_DEPTH: "0"

  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache

  script:
    - echo "Running SonarQube code analysis"
    - |
      mvn sonar:sonar \
        -f MyWebApp/pom.xml \
        -Dsonar.projectKey=MyWebApp \
        -Dsonar.host.url="${SONAR_HOST_URL}" \
        -Dsonar.token="${SONAR_TOKEN}" \
        -Dsonar.qualitygate.wait=true

  allow_failure: false


# -------------------------
# DEPLOY TO TOMCAT
# -------------------------

deploy_to_tomcat:
  stage: deploy
  image: curlimages/curl:latest

  dependencies:
    - build_war

  script:
    - echo "Deploying WAR file to Tomcat"
    - |
      curl --fail -v \
        -u "${TOMCAT_USER}:${TOMCAT_PASSWORD}" \
        -T MyWebApp/target/MyWebApp.war \
        "http://${TOMCAT_HOST}/manager/text/deploy?path=/MyWebApp&update=true"

Commit the file.


Step 5 – Pipeline Execution

As soon as you commit .gitlab-ci.yml, GitLab creates and starts the pipeline.

Go to:

Build → Pipelines

You should see the pipeline execute in this order:

1. Build

Maven compiles the Java application and generates the WAR file.

↓

2. Trivy Security Scan

Trivy scans the project filesystem and dependencies for known vulnerabilities.

If vulnerabilities matching the configured HIGH or CRITICAL severity threshold are detected, the Trivy command returns a non-zero exit code and the pipeline stops.

↓

3. SonarQube Code Analysis

SonarQube analyzes the application code.

The pipeline waits for the SonarQube Quality Gate result because we configured:

-Dsonar.qualitygate.wait=true

If the Quality Gate fails, the SonarQube job fails and deployment does not proceed.

↓

4. Deploy to Tomcat

Only when the previous stages succeed does GitLab execute the deployment job.

The WAR artifact generated during the build stage is deployed to Tomcat using the Tomcat Manager API.


Step 6 – Verify Trivy Security Scan

Go to:
GitLab → Build → Pipelines → trivy_scan
Review the Trivy scan results in the job log.
If no HIGH or CRITICAL vulnerabilities matching the configured criteria are found, the job passes and the pipeline continues.
If HIGH or CRITICAL vulnerabilities are detected, the job fails because we configured:
--severity HIGH,CRITICAL --exit-code 1

Step 7 – Verify the SonarQube Report

Login to SonarQube and open the project.

Review the analysis results, including the applicable:

  • Bugs
  • Vulnerabilities
  • Code Smells
  • Security Hotspots
  • Duplications
  • Coverage
  • Quality Gate status

Verify that the Quality Gate shows PASSED.


Step 8 – Verify the Application

After the pipeline completes successfully, open the Java web application running on Tomcat.

http://<TOMCAT-PUBLIC-DNS>:8080/MyWebApp

You should see the deployed Java web application.

The complete DevSecOps workflow is now:

Developer

↓

GitLab Repository

↓

GitLab Runner

↓

Maven Build

↓

Trivy Security Scan

↓

SonarQube Code Analysis

↓

Quality Gate

↓

Tomcat Deployment

↓

Java Web Application

Key Takeaway

GitLab manages and orchestrates the CI/CD pipeline, while GitLab Runner executes the jobs using the Docker images defined in .gitlab-ci.yml.

The application is deployed only after the configured Trivy security check and SonarQube Quality Gate succeed, providing security and quality checks before deployment.

YouTube video link:

No comments:

Post a Comment

How to Configure GitLab Runner with Docker Executor on Ubuntu 24.04 EC2

How to Configure GitLab Runner with Docker Executor on Ubuntu 24.04 EC2 In this tutorial, we will configure a self-hosted GitLab R...