Friday, September 25, 2026

How to Integrate SonarQube and Trivy with GitLab CI/CD | DevSecOps Pipeline

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.


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:

VariablePurpose
SONAR_HOST_URLSonarQube server URL
SONAR_TOKENSonarQube authentication token
TOMCAT_HOSTTomcat hostname/IP and port
TOMCAT_USERTomcat Manager username
TOMCAT_PASSWORDTomcat 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 for 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 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 7 – Verify the Application

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

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.

No comments:

Post a Comment

How to Integrate SonarQube and Trivy with GitLab CI/CD | DevSecOps Pipeline

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