π‘οΈ Building a DevSecOps Pipeline β Phase 1: Local Testing with Maven, SonarQube, Trivy & JFrog Artifactory


π Hands-on. Real-world. Secure-by-default. This post documents how I locally built and tested a DevSecOps pipeline using industry-standard tools before moving to Jenkins automation.
ποΈ Objective
To build and validate a local DevSecOps workflow that mimics a secure CI/CD pipeline. The tools were installed on separate EC2 instances, integrated manually, and tested end-to-end.
π§ Tech Stack
βοΈ Maven β Java build tool for compiling, testing, and packaging
π¬ SonarQube β Code quality and static analysis (via JaCoCo)
π‘οΈ Trivy β Dependency scanning and vulnerability management
π¦ JFrog Artifactory OSS β Artifact storage (Maven .jar deployment)
π» Infrastructure Architecture
EC2 Instance 1 (t2.medium):
OS: Ubuntu 24.04
Installed and configured SonarQube 10.5.1 with Nginx reverse proxy
Used embedded database for simplicity
SonarQube UI accessible via public IP/domain
EC2 Instance 2 (t2.large):
Tools installed: OpenJDK 17, Maven, Trivy, JFrog Artifactory OSS 7.71.23
Artifactory uses Derby (embedded DB)
Local Maven builds & Trivy scans performed here
Artifactory web UI running on port 8082
βοΈ Tool Configuration & Highlights
β Maven Build & Deploy
mvn clean
mvn test
mvn package
mvn deploy
distributionManagement in pom.xml
<distributionManagement>
<repository>
<id>jfrog-artifactory</id>
<name>JFrog Maven Local Repository</name>
<url>http://<your-artifactory-ip>:8082/artifactory/maven-local</url>
</repository>
</distributionManagement>
β SonarQube Static Analysis
Used jacoco-maven-plugin for code coverage
Results published to SonarQube UI
Triggered using Maven goal:
mvn clean verify sonar:sonar \ -Dsonar.login=$SONAR_TOKEN \ -Dsonar.host.url=http://<sonarqube-ip>:9000 \ -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
sonar.projectKey=my-app
sonar.projectName=My App
sonar.projectVersion=1.0
sonar.host.url=http://<sonarqube-ip>:9000
sonar.sources=src/main/java
sonar.tests=src/test/java
sonar.java.binaries=target/classes
sonar.java.test.binaries=target/test-classes
sonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
β Trivy Vulnerability Scanning
Scanned the source dependencies (not JAR directly β best practice):
trivy fs --exit-code 1 --severity HIGH,CRITICAL .
Also generated SBOM using Syft + Trivy:
syft ./target/my-app-1.0-SNAPSHOT.jar -o spdx-json > sbom.spdx.json
trivy sbom sbom.spdx.json
β JFrog Artifactory Setup (Highlights)
Installed Artifactory OSS 7.71.23
Chose this version because it uses embedded Derby DB, simplifying setup
Manual startup:
/opt/jfrog/app/bin/artifactory.sh start
Verified via:
curl http://localhost:8082
Exposed via EC2 IP + port
Configured Maven settings.xml with credentials and repository info
π§ͺ Local Testing Summary
βοΈ Build: mvn clean test package
βοΈ Static Analysis: SonarQube (via Jacoco)
βοΈ Security Scan: Trivy (on FS and dependencies)
βοΈ Artifact Deploy: mvn deploy to JFrog Artifactory
βοΈ Validation: All tool UIs confirmed expected outputs
π Whatβs Next?
π§ Phase 2 β Jenkins Automation:
Now that local testing is validated, Iβll automate the full DevSecOps flow using Jenkins:
Build β Test β Static Scan β Security Scan β Artifact Deploy
All triggered via Git-based Webhook pipeline
Stay tuned β Iβll share that in my next post!
π€ Letβs Connect
Iβm building and learning in public to stay focused, attract meaningful DevOps opportunities, and grow in the open. You can also connect with me on [LinkedIn](https://www.linkedin.com/in/kkintech15/) where I post DevOps projects regularly.
Thanks for reading!
π Tags
#DevOps #DevSecOps #SonarQube #Trivy #JFrog #Maven #CI/CD #AWS #BuildInPublic #LearningInPublic #Hashnode
Subscribe to my newsletter
Read articles from KkInTech15 directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
