diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..8d9590aa
Binary files /dev/null and b/.gitignore differ
diff --git a/DevOps-Project-18/README.md b/DevOps-Project-18/README.md
index 42138c7b..9eed70df 100644
--- a/DevOps-Project-18/README.md
+++ b/DevOps-Project-18/README.md
@@ -1,84 +1,58 @@
-# Jenkins Pipeline for Java based application using Maven, SonarQube, Argo CD, Helm and Kubernetes
+# Spring Boot CI/CD Pipeline with Jenkins, Docker, Helm & AKS
-
+## Overview
-## š BLOG URL HERE: https://harshhaa.hashnode.dev/streamlining-cicd-workflow-with-github-jenkins-sonarqube-docker-argocd-and-gitops
+This project implements an end-to-end CI/CD pipeline for a Spring Boot application using:
-Here are the step-by-step details to set up an **end-to-end Jenkins pipeline for a Java application using SonarQube, Argo CD, Helm, and Kubernetes:**
+- GitHub
+- Jenkins
+- Maven
+- Docker
+- Docker Hub
+- Helm
+- Kubernetes
+- Azure Kubernetes Service (AKS)
-**Prerequisites:**
-
-- Java application code hosted on a Git repository
-- Jenkins server
-- Kubernetes cluster
-- Helm package manager
-- Argo CD
-
-**Steps:**
-
- 1. Install the necessary Jenkins plugins:
- 1.1 Git plugin
- 1.2 Maven Integration plugin
- 1.3 Pipeline plugin
- 1.4 Kubernetes Continuous Deploy plugin
-
- 2. Create a new Jenkins pipeline:
- 2.1 In Jenkins, create a new pipeline job and configure it with the Git repository URL for the Java application.
- 2.2 Add a Jenkinsfile to the Git repository to define the pipeline stages.
-
- 3. Define the pipeline stages:
- Stage 1: Checkout the source code from Git.
- Stage 2: Build the Java application using Maven.
- Stage 3: Run unit tests using JUnit and Mockito.
- Stage 4: Run SonarQube analysis to check the code quality.
- Stage 5: Package the application into a JAR file.
- Stage 6: Deploy the application to a test environment using Helm.
- Stage 7: Run user acceptance tests on the deployed application.
- Stage 8: Promote the application to a production environment using Argo CD.
-
- 4. Configure Jenkins pipeline stages:
- Stage 1: Use the Git plugin to check out the source code from the Git repository.
- Stage 2: Use the Maven Integration plugin to build the Java application.
- Stage 3: Use the JUnit and Mockito plugins to run unit tests.
- Stage 4: Use the SonarQube plugin to analyze the code quality of the Java application.
- Stage 5: Use the Maven Integration plugin to package the application into a JAR file.
- Stage 6: Use the Kubernetes Continuous Deploy plugin to deploy the application to a test environment using Helm.
- Stage 7: Use a testing framework like Selenium to run user acceptance tests on the deployed application.
- Stage 8: Use Argo CD to promote the application to a production environment.
-
- 5. Set up Argo CD:
- Install Argo CD on the Kubernetes cluster.
- Set up a Git repository for Argo CD to track the changes in the Helm charts and Kubernetes manifests.
- Create a Helm chart for the Java application that includes the Kubernetes manifests and Helm values.
- Add the Helm chart to the Git repository that Argo CD is tracking.
-
- 6. Configure Jenkins pipeline to integrate with Argo CD:
- 6.1 Add the Argo CD API token to Jenkins credentials.
- 6.2 Update the Jenkins pipeline to include the Argo CD deployment stage.
-
- 7. Run the Jenkins pipeline:
- 7.1 Trigger the Jenkins pipeline to start the CI/CD process for the Java application.
- 7.2 Monitor the pipeline stages and fix any issues that arise.
-
-This end-to-end Jenkins pipeline will automate the entire CI/CD process for a Java application, from code checkout to production deployment, using popular tools like SonarQube, Argo CD, Helm, and Kubernetes.
-
-## š ļø Author & Community
-
-This project is crafted by **[Harshhaa](https://github.com/NotHarshhaa)** š”.
-Iād love to hear your feedback! Feel free to share your thoughts.
-
-š§ **Connect with me:**
-
-- **GitHub**: [@NotHarshhaa](https://github.com/NotHarshhaa)
-- **Blog**: [ProDevOpsGuy](https://blog.prodevopsguytech.com)
-- **Telegram Community**: [Join Here](https://t.me/prodevopsguy)
+The pipeline automatically builds the application, creates and publishes a Docker image, deploys the corresponding image version to AKS using Helm, and verifies the Kubernetes rollout.
---
-## ā Support the Project
-
-If you found this helpful, consider **starring** ā the repository and sharing it with your network! š
-
-### š¢ Stay Connected
-
-
+## Architecture
+
+```text
+ GitHub
+ |
+ | SCM Polling
+ v
+ +---------+
+ | Jenkins |
+ | Azure VM|
+ +----+----+
+ |
+ +--------+--------+
+ | |
+ v v
+ Maven Build Docker Build
+ | |
+ v v
+ Spring Boot Docker Image
+ JAR :BUILD_NUMBER
+ |
+ v
+ +-------------+
+ | Docker Hub |
+ +------+------+
+ |
+ v
+ Helm
+ |
+ v
+ +-------------+
+ | AKS |
+ | project18 |
+ +------+------+
+ |
+ +------+------+
+ | |
+ v v
+ Pod Pod
\ No newline at end of file
diff --git a/DevOps-Project-18/helm/spring-boot-app/.helmignore b/DevOps-Project-18/helm/spring-boot-app/.helmignore
new file mode 100644
index 00000000..0e8a0eb3
--- /dev/null
+++ b/DevOps-Project-18/helm/spring-boot-app/.helmignore
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/DevOps-Project-18/helm/spring-boot-app/Chart.yaml b/DevOps-Project-18/helm/spring-boot-app/Chart.yaml
new file mode 100644
index 00000000..e9799448
--- /dev/null
+++ b/DevOps-Project-18/helm/spring-boot-app/Chart.yaml
@@ -0,0 +1,24 @@
+apiVersion: v2
+name: spring-boot-app
+description: A Helm chart for Kubernetes
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+# Versions are expected to follow Semantic Versioning (https://semver.org/)
+version: 0.1.0
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application. Versions are not expected to
+# follow Semantic Versioning. They should reflect the version the application is using.
+# It is recommended to use it with quotes.
+appVersion: "1.16.0"
diff --git a/DevOps-Project-18/helm/spring-boot-app/templates/_helpers.tpl b/DevOps-Project-18/helm/spring-boot-app/templates/_helpers.tpl
new file mode 100644
index 00000000..e8d809b0
--- /dev/null
+++ b/DevOps-Project-18/helm/spring-boot-app/templates/_helpers.tpl
@@ -0,0 +1,62 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "spring-boot-app.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "spring-boot-app.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "spring-boot-app.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "spring-boot-app.labels" -}}
+helm.sh/chart: {{ include "spring-boot-app.chart" . }}
+{{ include "spring-boot-app.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "spring-boot-app.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "spring-boot-app.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "spring-boot-app.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "spring-boot-app.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
diff --git a/DevOps-Project-18/helm/spring-boot-app/templates/deployment.yaml b/DevOps-Project-18/helm/spring-boot-app/templates/deployment.yaml
new file mode 100644
index 00000000..01257f99
--- /dev/null
+++ b/DevOps-Project-18/helm/spring-boot-app/templates/deployment.yaml
@@ -0,0 +1,40 @@
+apiVersion: argoproj.io/v1alpha1
+kind: Rollout
+metadata:
+ name: {{ include "spring-boot-app.fullname" . }}
+ labels:
+ {{- include "spring-boot-app.labels" . | nindent 4 }}
+
+spec:
+ replicas: {{ .Values.replicaCount }}
+ strategy:
+ canary:
+ steps:
+ - setWeight: 50
+ - pause:
+ duration: 30s
+ selector:
+ matchLabels:
+ {{- include "spring-boot-app.selectorLabels" . | nindent 6 }}
+
+ template:
+ metadata:
+ labels:
+ {{- include "spring-boot-app.selectorLabels" . | nindent 8 }}
+
+ spec:
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+
+ securityContext:
+ runAsNonRoot: true
+
+ ports:
+ - name: http
+ containerPort: {{ .Values.service.targetPort }}
+ protocol: TCP
+
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
diff --git a/DevOps-Project-18/helm/spring-boot-app/templates/ingress.yaml b/DevOps-Project-18/helm/spring-boot-app/templates/ingress.yaml
new file mode 100644
index 00000000..ae282d08
--- /dev/null
+++ b/DevOps-Project-18/helm/spring-boot-app/templates/ingress.yaml
@@ -0,0 +1,17 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: {{ include "spring-boot-app.fullname" . }}
+spec:
+ ingressClassName: nginx
+
+ rules:
+ - http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: {{ include "spring-boot-app.fullname" . }}-service
+ port:
+ number: {{ .Values.service.port }}
diff --git a/DevOps-Project-18/helm/spring-boot-app/templates/service.yaml b/DevOps-Project-18/helm/spring-boot-app/templates/service.yaml
new file mode 100644
index 00000000..0d6fbec0
--- /dev/null
+++ b/DevOps-Project-18/helm/spring-boot-app/templates/service.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "spring-boot-app.fullname" . }}-service
+ labels:
+ {{- include "spring-boot-app.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - name: http
+ port: {{ .Values.service.port }}
+ targetPort: {{ .Values.service.targetPort }}
+ protocol: TCP
+ selector:
+ {{- include "spring-boot-app.selectorLabels" . | nindent 4 }}
\ No newline at end of file
diff --git a/DevOps-Project-18/helm/spring-boot-app/values.yaml b/DevOps-Project-18/helm/spring-boot-app/values.yaml
new file mode 100644
index 00000000..16605fe1
--- /dev/null
+++ b/DevOps-Project-18/helm/spring-boot-app/values.yaml
@@ -0,0 +1,19 @@
+replicaCount: 2
+
+image:
+ repository: tushar31/spring-boot-app
+ tag: "1"
+ pullPolicy: IfNotPresent
+
+service:
+ type: ClusterIP
+ port: 80
+ targetPort: 8080
+
+resources:
+ requests:
+ cpu: 40m
+ memory: 128Mi
+ limits:
+ cpu: 100m
+ memory: 220Mi
diff --git a/DevOps-Project-18/kyverno/require-non-root.yaml b/DevOps-Project-18/kyverno/require-non-root.yaml
new file mode 100644
index 00000000..3e9f8bda
--- /dev/null
+++ b/DevOps-Project-18/kyverno/require-non-root.yaml
@@ -0,0 +1,29 @@
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+ name: require-non-root
+ annotations:
+ policies.kyverno.io/title: Require Non-Root Containers
+ policies.kyverno.io/category: Pod Security
+ policies.kyverno.io/severity: medium
+ policies.kyverno.io/description: >-
+ Containers must not run as root.
+spec:
+ validationFailureAction: Enforce
+ background: true
+
+ rules:
+ - name: check-run-as-non-root
+ match:
+ any:
+ - resources:
+ kinds:
+ - Pod
+
+ validate:
+ message: "Containers must run as non-root."
+ pattern:
+ spec:
+ containers:
+ - securityContext:
+ runAsNonRoot: true
diff --git a/DevOps-Project-18/network-policy/[1m[Help b/DevOps-Project-18/network-policy/[1m[Help
new file mode 100644
index 00000000..e69de29b
diff --git a/DevOps-Project-18/network-policy/spring-boot-network-policy.yaml b/DevOps-Project-18/network-policy/spring-boot-network-policy.yaml
new file mode 100644
index 00000000..8472e53f
--- /dev/null
+++ b/DevOps-Project-18/network-policy/spring-boot-network-policy.yaml
@@ -0,0 +1,42 @@
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: spring-boot-network-policy
+ namespace: project18
+
+spec:
+ podSelector:
+ matchLabels:
+ app.kubernetes.io/name: spring-boot-app
+
+ policyTypes:
+ - Ingress
+ - Egress
+
+ ingress:
+ # Allow traffic from pods in project18
+ - from:
+ - podSelector:
+ matchLabels:
+ app.kubernetes.io/name: spring-boot-app
+
+ ports:
+ - protocol: TCP
+ port: 8080
+
+ egress:
+ # Allow communication to pods in project18
+ - to:
+ - podSelector: {}
+
+ # Allow DNS
+ - to:
+ - namespaceSelector:
+ matchLabels:
+ kubernetes.io/metadata.name: kube-system
+ ports:
+ - protocol: UDP
+ port: 53
+ - protocol: TCP
+ port: 53
+
diff --git a/DevOps-Project-18/network-test.yaml b/DevOps-Project-18/network-test.yaml
new file mode 100644
index 00000000..f3f29bdd
--- /dev/null
+++ b/DevOps-Project-18/network-test.yaml
@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: network-test
+ namespace: project18
+spec:
+ containers:
+ - name: network-test
+ image: curlimages/curl
+ command: ["sleep", "3600"]
+ securityContext:
+ runAsNonRoot: true
+ runAsUser: 1000
+
diff --git a/DevOps-Project-18/rbac/role.yaml b/DevOps-Project-18/rbac/role.yaml
new file mode 100644
index 00000000..1d2579f4
--- /dev/null
+++ b/DevOps-Project-18/rbac/role.yaml
@@ -0,0 +1,9 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: spring-boot-role
+ namespace: project18
+rules:
+ - apiGroups: [""]
+ resources: ["pods"]
+ verbs: ["get", "list"]
\ No newline at end of file
diff --git a/DevOps-Project-18/rbac/rolebinding.yaml b/DevOps-Project-18/rbac/rolebinding.yaml
new file mode 100644
index 00000000..a3824ee4
--- /dev/null
+++ b/DevOps-Project-18/rbac/rolebinding.yaml
@@ -0,0 +1,13 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: spring-boot-rolebinding
+ namespace: project18
+subjects:
+ - kind: ServiceAccount
+ name: spring-boot-sa
+ namespace: project18
+roleRef:
+ kind: Role
+ name: spring-boot-role
+ apiGroup: rbac.authorization.k8s.io
\ No newline at end of file
diff --git a/DevOps-Project-18/rbac/serviceaccount.yaml b/DevOps-Project-18/rbac/serviceaccount.yaml
new file mode 100644
index 00000000..aa6f6891
--- /dev/null
+++ b/DevOps-Project-18/rbac/serviceaccount.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: spring-boot-sa
+ namespace: project18
\ No newline at end of file
diff --git a/DevOps-Project-18/spring-boot-app-manifests/deployment.yml b/DevOps-Project-18/spring-boot-app-manifests/deployment.yml
deleted file mode 100644
index 5bdfe5aa..00000000
--- a/DevOps-Project-18/spring-boot-app-manifests/deployment.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: spring-boot-app
- labels:
- app: spring-boot-app
-spec:
- replicas: 2
- selector:
- matchLabels:
- app: spring-boot-app
- template:
- metadata:
- labels:
- app: spring-boot-app
- spec:
- containers:
- - name: spring-boot-app
- image: abhishekf5/ultimate-cicd:replaceImageTag
- ports:
- - containerPort: 8080
diff --git a/DevOps-Project-18/spring-boot-app-manifests/service.yml b/DevOps-Project-18/spring-boot-app-manifests/service.yml
deleted file mode 100644
index 400af546..00000000
--- a/DevOps-Project-18/spring-boot-app-manifests/service.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
- name: spring-boot-app-service
-spec:
- type: NodePort
- ports:
- - name: http
- port: 80
- targetPort: 8080
- protocol: TCP
- selector:
- app: spring-boot-app
diff --git a/DevOps-Project-18/spring-boot-app/.gitignore b/DevOps-Project-18/spring-boot-app/.gitignore
new file mode 100644
index 00000000..9f970225
--- /dev/null
+++ b/DevOps-Project-18/spring-boot-app/.gitignore
@@ -0,0 +1 @@
+target/
\ No newline at end of file
diff --git a/DevOps-Project-18/spring-boot-app/Dockerfile b/DevOps-Project-18/spring-boot-app/Dockerfile
index fe9c5d89..2fc59b11 100644
--- a/DevOps-Project-18/spring-boot-app/Dockerfile
+++ b/DevOps-Project-18/spring-boot-app/Dockerfile
@@ -1,13 +1,18 @@
-# You can change this base image to anything else
-# But make sure to use the correct version of Java
-FROM adoptopenjdk/openjdk11:alpine-jre
+FROM eclipse-temurin:17-jre-alpine
+
+RUN apk update && apk upgrade
-# Simply the artifact path
ARG artifact=target/spring-boot-web.jar
WORKDIR /opt/app
COPY ${artifact} app.jar
-# This should not be changed
-ENTRYPOINT ["java","-jar","app.jar"]
+RUN addgroup -S -g 10001 appgroup && \
+ adduser -S -u 10001 -G appgroup appuser
+
+RUN chown -R 10001:10001 /opt/app
+
+USER 10001
+
+ENTRYPOINT ["java", "-jar", "app.jar"]
\ No newline at end of file
diff --git a/DevOps-Project-18/spring-boot-app/JenkinsFile b/DevOps-Project-18/spring-boot-app/JenkinsFile
index a5bb5456..6bd11ad1 100644
--- a/DevOps-Project-18/spring-boot-app/JenkinsFile
+++ b/DevOps-Project-18/spring-boot-app/JenkinsFile
@@ -1,68 +1,137 @@
pipeline {
- agent {
- docker {
- image 'abhishekf5/maven-abhishek-docker-agent:v1'
- args '--user root -v /var/run/docker.sock:/var/run/docker.sock' // mount Docker socket to access the host's Docker daemon
+ agent any
+
+ environment {
+ DOCKER_IMAGE = "tushar31/spring-boot-app:${BUILD_NUMBER}"
+ APP_URL = "http://4.157.219.55/"
}
- }
- stages {
- stage('Checkout') {
- steps {
- sh 'echo passed'
- //git branch: 'main', url: 'https://github.com/iam-veeramalla/Jenkins-Zero-To-Hero.git'
- }
- }
- stage('Build and Test') {
- steps {
- sh 'ls -ltr'
- // build the project and create a JAR file
- sh 'cd java-maven-sonar-argocd-helm-k8s/spring-boot-app && mvn clean package'
- }
+
+ stages {
+
+ stage('Build Application') {
+ steps {
+ dir('DevOps-Project-18/spring-boot-app') {
+ sh 'mvn clean package'
+ }
+ }
+ }
+stage('SonarQube Analysis') {
+ steps {
+ script {
+ def scannerHome = tool 'sonar-scanner'
+
+ dir('DevOps-Project-18/spring-boot-app') {
+ withSonarQubeEnv('SonarQube') {
+ withCredentials([
+ string(
+ credentialsId: 'sonarqube-token',
+ variable: 'SONAR_TOKEN'
+ )
+ ]) {
+ sh """
+ ${scannerHome}/bin/sonar-scanner \
+ -Dsonar.projectKey=my-app \
+ -Dsonar.projectName=my-app \
+ -Dsonar.sources=src/main/java \
+ -Dsonar.java.binaries=target/classes \
+ -Dsonar.token=\$SONAR_TOKEN
+ """
+ }
+ }
+ }
+ }
}
- stage('Static Code Analysis') {
- environment {
- SONAR_URL = "http://34.201.116.83:9000"
- }
- steps {
- withCredentials([string(credentialsId: 'sonarqube', variable: 'SONAR_AUTH_TOKEN')]) {
- sh 'cd java-maven-sonar-argocd-helm-k8s/spring-boot-app && mvn sonar:sonar -Dsonar.login=$SONAR_AUTH_TOKEN -Dsonar.host.url=${SONAR_URL}'
+}
+stage('OWASP Dependency Check') {
+ steps {
+ dir('DevOps-Project-18/spring-boot-app') {
+ withCredentials([string(credentialsId: 'nvd-api-key', variable: 'NVD_API_KEY')]) {
+ sh """
+ export NVD_API_KEY=\$(printf '%s' '${NVD_API_KEY}' | tr -d '\\r' | tr -d '\\n')
+ mvn org.owasp:dependency-check-maven:13.0.0:check \
+ -DnvdApiKey="\$NVD_API_KEY" \
+ -DfailBuildOnCVSS=8
+"""
+ }
}
- }
}
- stage('Build and Push Docker Image') {
- environment {
- DOCKER_IMAGE = "abhishekf5/ultimate-cicd:${BUILD_NUMBER}"
- // DOCKERFILE_LOCATION = "java-maven-sonar-argocd-helm-k8s/spring-boot-app/Dockerfile"
- REGISTRY_CREDENTIALS = credentials('docker-cred')
- }
- steps {
- script {
- sh 'cd java-maven-sonar-argocd-helm-k8s/spring-boot-app && docker build -t ${DOCKER_IMAGE} .'
- def dockerImage = docker.image("${DOCKER_IMAGE}")
- docker.withRegistry('https://index.docker.io/v1/', "docker-cred") {
- dockerImage.push()
+}
+
+ stage('Build Docker Image') {
+ steps {
+ dir('DevOps-Project-18/spring-boot-app') {
+ sh 'docker build -t ${DOCKER_IMAGE} .'
+ }
}
}
- }
+ stage('Trivy Image Scan') {
+ steps {
+ sh '''
+ trivy image \
+ --severity HIGH,CRITICAL \
+ --exit-code 1 \
+ ${DOCKER_IMAGE}
+ '''
}
- stage('Update Deployment File') {
- environment {
- GIT_REPO_NAME = "Jenkins-Zero-To-Hero"
- GIT_USER_NAME = "iam-veeramalla"
+}
+
+ stage('Push Docker Image') {
+ steps {
+ script {
+ docker.withRegistry(
+ 'https://index.docker.io/v1/',
+ 'docker-cred'
+ ) {
+ docker.image("${DOCKER_IMAGE}").push()
+ }
+ }
+ }
}
- steps {
- withCredentials([string(credentialsId: 'github', variable: 'GITHUB_TOKEN')]) {
+
+ stage('Deploy to AKS') {
+ steps {
sh '''
- git config user.email "abhishek.xyz@gmail.com"
- git config user.name "Abhishek Veeramalla"
- BUILD_NUMBER=${BUILD_NUMBER}
- sed -i "s/replaceImageTag/${BUILD_NUMBER}/g" java-maven-sonar-argocd-helm-k8s/spring-boot-app-manifests/deployment.yml
- git add java-maven-sonar-argocd-helm-k8s/spring-boot-app-manifests/deployment.yml
- git commit -m "Update deployment image to version ${BUILD_NUMBER}"
- git push https://${GITHUB_TOKEN}@github.com/${GIT_USER_NAME}/${GIT_REPO_NAME} HEAD:main
+ helm upgrade --install spring-boot-app \
+ ./DevOps-Project-18/helm/spring-boot-app \
+ --namespace project18 \
+ --create-namespace \
+ --set image.repository=tushar31/spring-boot-app \
+ --set image.tag=${BUILD_NUMBER} \
+ --wait \
+ --timeout 2m
'''
}
}
+
+ stage('Verify Deployment') {
+ steps {
+ sh '''
+ kubectl get pods -n project18
+ kubectl argo rollouts status spring-boot-app -n project18 --timeout=120s
+ '''
+ }
+ }
+
+stage('OWASP ZAP DAST') {
+ steps {
+ sh '''
+ docker run --rm \
+ --user 0 \
+ -v "$WORKSPACE:/zap/wrk/:rw" \
+ ghcr.io/zaproxy/zaproxy:stable \
+ zap-baseline.py \
+ -t http://4.157.219.55/ \
+ -r zap-report.html \
+ -I
+ '''
+ }
+
+ post {
+ always {
+ archiveArtifacts artifacts: 'zap-report.html',
+ allowEmptyArchive: true
+ }
}
- }
}
+ }
+}
\ No newline at end of file
diff --git a/DevOps-Project-18/spring-boot-app/README.md b/DevOps-Project-18/spring-boot-app/README.md
index dfdd1f00..7a3a16bc 100644
--- a/DevOps-Project-18/spring-boot-app/README.md
+++ b/DevOps-Project-18/spring-boot-app/README.md
@@ -5,7 +5,7 @@ at the root directory of the repository.
This is a MVC architecture based application where controller returns a page with title and message attributes to the view.
-## Execute the application locally and access it using your browser
+## Execute the application locally and access It using your browser
Checkout the repo and move to the directory
diff --git a/DevOps-Project-18/spring-boot-app/pom.xml b/DevOps-Project-18/spring-boot-app/pom.xml
index fed87b6f..5a0b6b66 100644
--- a/DevOps-Project-18/spring-boot-app/pom.xml
+++ b/DevOps-Project-18/spring-boot-app/pom.xml
@@ -14,14 +14,17 @@
org.springframework.boot
spring-boot-starter-parent
- 2.2.4.RELEASE
+ 4.1.0
UTF-8
- 11
- 11
- 11
+ 17
+ 17
+ 17
+ 17
+ 13.0.0
+ 11.0.24
@@ -40,12 +43,7 @@
test
-
-
- org.springframework.boot
- spring-boot-devtools
- true
-
+
@@ -54,6 +52,7 @@
spring-boot-web
+
org.springframework.boot
spring-boot-maven-plugin
@@ -61,10 +60,23 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.8.0
+ 3.11.0
+
+ ${maven.compiler.source}
+ ${maven.compiler.target}
+ ${maven.compiler.release}
+
+
+
+ org.owasp
+ dependency-check-maven
+ ${dependency-check.version}
- ${java.version}
- ${java.version}
+ 8
+
+ HTML
+ JSON
+
diff --git a/DevOps-Project-18/spring-boot-app/src/main/java/com/abhishek/StartApplication.java b/DevOps-Project-18/spring-boot-app/src/main/java/com/abhishek/StartApplication.java
index 89f846e8..8ef9ac3a 100644
--- a/DevOps-Project-18/spring-boot-app/src/main/java/com/abhishek/StartApplication.java
+++ b/DevOps-Project-18/spring-boot-app/src/main/java/com/abhishek/StartApplication.java
@@ -13,7 +13,7 @@ public class StartApplication {
@GetMapping("/")
public String index(final Model model) {
model.addAttribute("title", "I have successfuly built a sprint boot application using Maven");
- model.addAttribute("msg", "This application is deployed on to Kubernetes using Argo CD");
+ model.addAttribute("msg", "This Application is Deployed on to Kubernetes using Argo CD");
return "index";
}
diff --git a/DevOps-Project-18/spring-boot-app/target/classes/application.properties b/DevOps-Project-18/spring-boot-app/target/classes/application.properties
new file mode 100644
index 00000000..ad334447
--- /dev/null
+++ b/DevOps-Project-18/spring-boot-app/target/classes/application.properties
@@ -0,0 +1 @@
+# nothing here yet
diff --git a/DevOps-Project-18/spring-boot-app/target/classes/com/abhishek/StartApplication.class b/DevOps-Project-18/spring-boot-app/target/classes/com/abhishek/StartApplication.class
new file mode 100644
index 00000000..8db8a550
Binary files /dev/null and b/DevOps-Project-18/spring-boot-app/target/classes/com/abhishek/StartApplication.class differ
diff --git a/DevOps-Project-18/spring-boot-app/target/classes/static/css/main.css b/DevOps-Project-18/spring-boot-app/target/classes/static/css/main.css
new file mode 100644
index 00000000..8a602448
--- /dev/null
+++ b/DevOps-Project-18/spring-boot-app/target/classes/static/css/main.css
@@ -0,0 +1,7 @@
+body {
+ padding-top: 5rem;
+}
+.starter-template {
+ padding: 3rem 1.5rem;
+ text-align: center;
+}
\ No newline at end of file
diff --git a/DevOps-Project-18/spring-boot-app/target/classes/static/js/main.js b/DevOps-Project-18/spring-boot-app/target/classes/static/js/main.js
new file mode 100644
index 00000000..e69de29b
diff --git a/DevOps-Project-18/spring-boot-app/target/classes/templates/index.html b/DevOps-Project-18/spring-boot-app/target/classes/templates/index.html
new file mode 100644
index 00000000..894fbcd2
--- /dev/null
+++ b/DevOps-Project-18/spring-boot-app/target/classes/templates/index.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+ CI/CD Master Class By Abhishek Veeramalla
+
+
+
+
+
+
+
+
Default title.
+
Default text.
+
+
+
+
+
+
+
diff --git a/DevOps-Project-18/spring-boot-app/target/maven-archiver/pom.properties b/DevOps-Project-18/spring-boot-app/target/maven-archiver/pom.properties
new file mode 100644
index 00000000..11ee3f2d
--- /dev/null
+++ b/DevOps-Project-18/spring-boot-app/target/maven-archiver/pom.properties
@@ -0,0 +1,3 @@
+artifactId=spring-boot-demo
+groupId=com.abhishek
+version=1.0
diff --git a/DevOps-Project-18/spring-boot-app/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/DevOps-Project-18/spring-boot-app/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 00000000..27f0babf
--- /dev/null
+++ b/DevOps-Project-18/spring-boot-app/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1 @@
+com\abhishek\StartApplication.class
diff --git a/DevOps-Project-18/spring-boot-app/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/DevOps-Project-18/spring-boot-app/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 00000000..451d9a3b
--- /dev/null
+++ b/DevOps-Project-18/spring-boot-app/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1 @@
+C:\Users\tusha\Downloads\DevOps-Projects\DevOps-Project-18\spring-boot-app\src\main\java\com\abhishek\StartApplication.java
diff --git a/DevOps-Project-18/spring-boot-app/target/spring-boot-web.jar b/DevOps-Project-18/spring-boot-app/target/spring-boot-web.jar
new file mode 100644
index 00000000..6c228947
Binary files /dev/null and b/DevOps-Project-18/spring-boot-app/target/spring-boot-web.jar differ
diff --git a/DevOps-Project-18/spring-boot-app/target/spring-boot-web.jar.original b/DevOps-Project-18/spring-boot-app/target/spring-boot-web.jar.original
new file mode 100644
index 00000000..ad113bea
Binary files /dev/null and b/DevOps-Project-18/spring-boot-app/target/spring-boot-web.jar.original differ