Overview :
Anchore :
Anchore is a comprehensive container security and compliance platform that enables you to analyze, inspect, and enforce policies on container images.
If you don’t have Anchore , follow these steps to install it on Ubuntu:
Why Integrate Anchore with Jenkins?
- Automate container image scanning as part of CI/CD.
- Enforce security and compliance policies early in the pipeline.
- Gain insights into vulnerabilities, license risks, and configuration issues in container images.
Steps for Anchore and Jenkins Integration :
a. Prerequisites :
- Install Jenkins and Anchore.
- Configure Anchore Engine
- Set up Docker to build images locally or use a container registry.
b. Installing Anchore Plugin in Jenkins :
- Navigate to Jenkins dashboard → Manage Jenkins → Plugins.
- Install the Anchore Container Image Scanner plugin.
c. Configuring Anchore in Jenkins :
- Go to Manage Jenkins → Configure System.
- Add Anchore Engine URL and API credentials.
d. Setting up Anchore in a Jenkins Pipeline :
Add the anchore
stage in your Jenkinsfile
.
Jenkinsfile is as Follows:
pipeline {
agent any
environment {
DOCKERHUB_CREDENTIALS = credentials('dockerhubpwd')
SLACK_CREDENTIALS = credentials('b3ee302b-e782-4d8e-ba83-7fa591d43205')
SONARQUBE_CREDENTIALS = credentials('sonar_d_token')
SONARQUBE_SERVER = 'http://localhost:9000'
ANCHORE_URL = 'http://localhost:8228'
ANCHORE_CREDENTIALS = credentials('anchor_id')
ANCHORE_CREDENTIALS_USR = 'admin'
ANCHORE_CREDENTIALS_PSW = 'foobar'
}
parameters {
string(name: 'JAVA_REPO', defaultValue: 'Your Repository name', description: 'Java Application Repository')
string(name: 'DOCKERHUB_USERNAME', defaultValue: 'your Dockerhub username', description: 'DockerHub Username')
string(name: 'JAVA_IMAGE_NAME', defaultValue: 'testhello', description: 'Java Docker Image Name')
string(name: 'JAVA_NAMESPACE', defaultValue: 'test', description: 'Kubernetes Namespace for Java Application')
}
stages {
stage('Clone Repository') {
steps {
git url: params.JAVA_REPO, branch: 'main'
}
}
stage('Build and Push Docker Image') {
steps {
dir('testhello') {
sh 'mvn clean install'
script {
def image = docker.build("${params.DOCKERHUB_USERNAME}/${params.JAVA_IMAGE_NAME}:${currentBuild.number}")
docker.withRegistry('', 'dockerhubpwd') {
image.push()
}
}
}
}
}
// Install Anchore CLI if not already installed
stage('Install Anchore CLI') {
steps {
sh '''
if ! command -v anchore-cli > /dev/null; then
pip install --user anchorecli
fi
'''
}
}
// Set Anchore CLI Path
stage('Set Anchore CLI Path') {
steps {
sh '''
export PATH=$PATH:/home/ubuntu/.local/bin
echo "Anchore CLI Path set to: $PATH"
'''
}
}
stage('Analyze Image with Anchore') {
steps {
withCredentials([usernamePassword(credentialsId: 'anchor_id', usernameVariable: 'ANCHORE_USER', passwordVariable: 'ANCHORE_PASS')]) {
sh """
export PATH=$PATH:/home/ubuntu/.local/bin
anchore-cli --url ${ANCHORE_URL} --u ${ANCHORE_CREDENTIALS_USR} --p ${ANCHORE_CREDENTIALS_PSW} image add ${params.DOCKERHUB_USERNAME}/${params.JAVA_IMAGE_NAME}:${currentBuild.number}
anchore-cli --url ${ANCHORE_URL} --u ${ANCHORE_CREDENTIALS_USR} --p ${ANCHORE_CREDENTIALS_PSW} image wait ${params.DOCKERHUB_USERNAME}/${params.JAVA_IMAGE_NAME}:${currentBuild.number}
anchore-cli --url ${ANCHORE_URL} --u ${ANCHORE_CREDENTIALS_USR} --p ${ANCHORE_CREDENTIALS_PSW} image vuln ${params.DOCKERHUB_USERNAME}/${params.JAVA_IMAGE_NAME}:${currentBuild.number} all
"""
}
}
}
stage('SonarQube Analysis') {
steps {
dir('testhello') {
withSonarQubeEnv('SonarQube') {
sh '''
mvn sonar:sonar \
-Dsonar.projectKey=testhello \
-Dsonar.host.url=${SONARQUBE_SERVER} \
-Dsonar.login=${SONARQUBE_CREDENTIALS}
'''
}
}
}
}
stage('Get Approval') {
steps {
script {
input message: 'Do you approve this deployment?', ok: 'Yes, deploy'
}
}
}
stage('Build and Package Java Helm Chart') {
steps {
dir('testhello') {
sh '''
"${WORKSPACE}/yq" e -i '.image.tag = "latest"' ./myspringbootchart/values.yaml
helm template ./myspringbootchart
helm lint ./myspringbootchart
helm package ./myspringbootchart --version "1.0.0"
'''
}
}
}
stage('Deploy Java Application to Kubernetes') {
steps {
script {
kubernetesDeploy(
configs: 'Build and Deploy Java and Python Applications',
kubeconfigId: 'kubeconfig1pwd'
)
}
}
}
}
post {
always {
script {
def slackBaseUrl = 'https://slack.com/api/'
def slackChannel = '#builds'
def slackColor = currentBuild.currentResult == 'SUCCESS' ? 'good' : 'danger'
def slackMessage = "Build ${currentBuild.fullDisplayName} finished with status: ${currentBuild.currentResult}"
echo "Sending Slack notification to ${slackChannel} with message: ${slackMessage}"
slackSend(
baseUrl: 'https://yourteam.slack.com/api/',
teamDomain: 'StarAppleInfotech',
channel: '#builds',
color: slackColor,
botUser: true,
tokenCredentialId: SLACK_CREDENTIALS,
notifyCommitters: false,
message: "Build Java Application #${env.BUILD_NUMBER} finished with status: ${currentBuild.currentResult}"
)
}
emailext(
to: 'your name@gmail.com',
subject: "Jenkins Build ${env.JOB_NAME} #${env.BUILD_NUMBER} ${currentBuild.currentResult}",
body: """<p>Build ${env.JOB_NAME} #${env.BUILD_NUMBER} finished with status: ${currentBuild.currentResult}</p>
<p>Check console output at ${env.BUILD_URL}</p>""",
mimeType: 'text/html'
)
}
failure {
emailext(
to: 'your name@gmail.com',
subject: "Jenkins Build ${env.JOB_NAME} #${env.BUILD_NUMBER} Failed",
body: """<p>Build ${env.JOB_NAME} #${env.BUILD_NUMBER} failed.</p>
<p>Check console output at ${env.BUILD_URL}</p>""",
mimeType: 'text/html'
)
}
success {
emailext(
to: 'yourname@gmail.com',
subject: "Jenkins Build ${env.JOB_NAME} #${env.BUILD_NUMBER} Succeeded",
body: """<p>Build ${env.JOB_NAME} #${env.BUILD_NUMBER} succeeded.</p>
<p>Check console output at ${env.BUILD_URL}</p>""",
mimeType: 'text/html'
)
}
}
}
Build this project and see the consol output ..
Latest posts by Mahesh Wabale (see all)
- Dependency Track – End To End CI/CD Pipeline - November 29, 2024
- Dependency-track Jenkins Integration - November 27, 2024
- Jenkins Setup for PyTest + Selenium Automation Testing - November 27, 2024