-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Add Kubernetes resource requests and limits to Helm chart And Added Helm Charts Deployment #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
e66fc7c
2129c6d
f63cc6b
036ab9c
d68398e
965210b
d864034
9045bbc
69e7c41
ff3d873
c8b3679
17aec96
066f7a1
0636efd
15b25e6
e76b225
c9baa17
574d1ab
43e3188
e051d15
59152cc
972c848
b800159
b8a481a
670bc34
5249b60
69ee975
3707de0
656e26e
7d0e041
fd9d6cd
56d48e1
67e5f33
0747132
6e0dfb4
4cd6c64
7116e3c
c402889
289ffeb
8b701c3
045448c
66b7340
17ba89f
26ac1de
d60d577
a4b203a
624d3fd
169e055
684ec7a
1faa7c5
675cb79
6c7ca73
b41ad81
1bc27a9
1431cc1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- Chart.yaml ---'
cat -n DevOps-Project-18/helm/spring-boot-app/Chart.yaml
printf '%s\n' '--- pom.xml version declarations ---'
rg -n -C 3 '<version>|<parent>|<artifactId>' DevOps-Project-18/spring-boot-app/pom.xml
printf '%s\n' '--- Helm helper references ---'
rg -n -C 4 'Chart\.AppVersion|app\.kubernetes\.io/version' DevOps-Project-18/helm/spring-boot-app/templates/_helpers.tpl
printf '%s\n' '--- Version references in the project ---'
rg -n -i 'appVersion|app\.kubernetes\.io/version|spring-boot-app|<version>' DevOps-Project-18 --glob '!target/**' --glob '!build/**' | head -200
printf '%s\n' '--- Read-only consistency probe ---'
python3 - <<'PY'
from pathlib import Path
import re
chart = Path("DevOps-Project-18/helm/spring-boot-app/Chart.yaml").read_text()
pom = Path("DevOps-Project-18/spring-boot-app/pom.xml").read_text()
helper = Path("DevOps-Project-18/helm/spring-boot-app/templates/_helpers.tpl").read_text()
chart_version = re.search(r'(?m)^appVersion:\s*["\']?([^"\']+)["\']?\s*$', chart)
pom_version = re.search(r'<project\b.*?</project>', pom, re.S)
pom_project_version = re.search(r'(?m)^\s*<version>\s*([^<]+)\s*</version>', pom)
helper_uses_chart = ".Chart.AppVersion" in helper
print({
"chart_appVersion": chart_version.group(1) if chart_version else None,
"pom_first_project_version": pom_project_version.group(1).strip() if pom_project_version else None,
"helper_uses_Chart_AppVersion": helper_uses_chart,
})
PYRepository: NotHarshhaa/DevOps-Projects Length of output: 7446 🏁 Script executed: # Awaiting capability results.Repository: NotHarshhaa/DevOps-Projects Length of output: 165 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- Jenkins pipeline ---'
cat -n DevOps-Project-18/spring-boot-app/JenkinsFile
printf '%s\n' '--- Deployment template ---'
cat -n DevOps-Project-18/helm/spring-boot-app/templates/deployment.yaml
printf '%s\n' '--- Values ---'
cat -n DevOps-Project-18/helm/spring-boot-app/values.yaml
printf '%s\n' '--- Release/version overrides ---'
rg -n -C 3 -- '--set|appVersion|BUILD_NUMBER|image:|tag:' DevOps-Project-18/spring-boot-app/JenkinsFile DevOps-Project-18/helm/spring-boot-appRepository: NotHarshhaa/DevOps-Projects Length of output: 6842 🏁 Script executed: # Awaiting capability results.Repository: NotHarshhaa/DevOps-Projects Length of output: 165 Align Set 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
Uh oh!
There was an error while loading. Please reload this page.