diff --git a/.gitignore b/.gitignore
index 549e00a2..660ed0da 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
-HELP.md
+dockeHELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
@@ -31,3 +31,8 @@ build/
### VS Code ###
.vscode/
+terraform/.terraform.lock.hcl
+terraform/bankapp-automate-key
+terraform/.terraform/providers/registry.terraform.io/hashicorp/aws/6.13.0/windows_amd64/terraform-provider-aws_v6.13.0_x5.exe
+terraform/terraform.tfstate
+terraform/.terraform/providers/registry.terraform.io/hashicorp/aws/6.13.0/windows_amd64/LICENSE.txt
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..cc9d5b53
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,18 @@
+# Stage 1
+FROM maven:3.8.3-openjdk-17 AS builder
+
+WORKDIR /src
+
+COPY . /src/
+
+RUN mvn clean install -DskipTests=true
+
+# Stage 2
+
+FROM openjdk:17-alpine
+
+COPY --from=builder /src/target/*.jar /src/target/bankapp.jar
+
+EXPOSE 8080
+
+CMD ["java","-jar","/src/target/bankapp.jar"]
\ No newline at end of file
diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644
index 00000000..4b1c570b
--- /dev/null
+++ b/Jenkinsfile
@@ -0,0 +1,39 @@
+pipeline{
+ agent any;
+
+ parameters {
+ string(name: 'IMAGE_VERSION', defaultValue: 'latest', description: 'Image tag')
+ }
+ stages{
+ stage("Code Clone"){
+ steps{
+ git url: "https://github.com/himanshi1107/BankApp_DevSecOps_EKS.git", branch: "main"
+ }
+ }
+ stage("Trivy Scan"){
+ steps{
+ sh "trivy fs ."
+ }
+ }
+ stage("Build"){
+ steps{
+ sh "docker build -t bankapp-eks:${params.IMAGE_VERSION} ."
+ }
+ }
+ stage("Push"){
+ steps{
+ withCredentials([usernamePassword(
+ credentialsId: "dockerHub",
+ usernameVariable: "dockerHubUser",
+ passwordVariable: "dockerHubPass")]) {
+ sh '''
+ docker login -u $dockerHubUser -p $dockerHubPass
+ docker image tag bankapp-eks:${IMAGE_VERSION} $dockerHubUser/bankapp-eks:${IMAGE_VERSION}
+ docker push $dockerHubUser/bankapp-eks:${IMAGE_VERSION}
+ '''
+ }
+
+ }
+ }
+ }
+}
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..1989bf95
--- /dev/null
+++ b/README.md
@@ -0,0 +1,87 @@
+# π¦ BankApp DevSecOps on AWS EKS using ArgoCD
+
+π A **production-ready Bank Application** featuring **CI/CD, security, and observability** β deployed on **AWS EKS** using modern **DevSecOps practices**.
+
+---
+
+## π οΈ Tech Stack
+
+- π **GitHub** β Code hosting & version control
+- π¦ **Docker** β Containerization
+- π **Jenkins** β Continuous Integration (CI)
+- π‘οΈ **OWASP** β Dependency vulnerability checks
+- π§Ή **SonarQube** β Code quality & static analysis
+- π **Trivy** β Filesystem & container image scanning
+- π **ArgoCD** β Continuous Delivery (CD)
+- βΈοΈ **AWS EKS** β Kubernetes orchestration
+- π **Helm** β Manifest templating & deployment
+- π **Grafana & Prometheus** β Monitoring & visualization
+
+---
+
+## π Application Overview
+
+This project demonstrates **end-to-end automation** for deploying a **secure, scalable, and highly available Spring Bootβbased banking application** on **AWS EKS**.
+
+βοΈ Integrated quality checks
+βοΈ Vulnerability scanning
+βοΈ Monitored production environments
+βοΈ Security & compliance at every stage
+
+π The architecture ensures **speed, reliability, and security** throughout the deployment lifecycle.
+
+---
+
+## ποΈ Architecture
+
+Below is the high-level architecture of the project:
+
+ 
+
+- **CI/CD**: Jenkins automates build, test, scan, and image push.
+- **Security**: OWASP, SonarQube, and Trivy ensure code and container security.
+- **CD**: ArgoCD automates deployment into AWS EKS.
+- **Observability**: Prometheus collects metrics, Grafana provides dashboards.
+
+---
+
+## β‘ Requirements & Notes
+
+- π **Deployment Region** β `us-east-1` (North Virginia)
+- π€ **AWS Access** β Root account / IAM user with sufficient permissions
+- π **System Access** β Requires `sudo` privileges
+- π **Security Groups** β Ensure ports are open as per reference screenshot
+- π₯οΈ **Master Node** β `t2.medium` (29GB storage)
+- βοΈ **Pre-setup** β AWS CLI, `kubectl`, and `eksctl` configured before cluster creation
+
+---
+
+## πΈ Key Screenshots
+
+- π» **Application UI**
+
+
+- βΈοΈ **AWS EKS Console**
+
+
+
+- π **ArgoCD Dashboard**
+
+
+
+
+- π³ **DockerHub Repository**
+
+
+- βοΈ **Jenkins CI Pipeline**
+
+
+- π **Grafana Monitoring**
+
+
+
+
+---
+
+β¨ With this setup, you get a **bank-grade application** deployed with **modern DevSecOps practices** β combining **automation, security, and observability** on the cloud.
+
diff --git a/kubernetes/bankapp-deployment.yml b/kubernetes/bankapp-deployment.yml
new file mode 100644
index 00000000..082a850b
--- /dev/null
+++ b/kubernetes/bankapp-deployment.yml
@@ -0,0 +1,62 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ labels:
+ app: bankapp-deploy
+ name: bankapp-deploy
+ namespace: bankapp-namespace
+spec:
+ replicas: 2 # Keep replicas >= 2 for high availability
+ selector:
+ matchLabels:
+ app: bankapp-deploy
+ template:
+ metadata:
+ labels:
+ app: bankapp-deploy
+ spec:
+ containers:
+ - name: bankapp
+ image: himanshi1107/bankapp-eks:v1
+ ports:
+ - containerPort: 8080
+ env:
+ - name: SPRING_DATASOURCE_URL
+ valueFrom:
+ configMapKeyRef:
+ name: bankapp-config
+ key: SPRING_DATASOURCE_URL
+ - name: SPRING_DATASOURCE_USERNAME
+ valueFrom:
+ configMapKeyRef:
+ name: bankapp-config
+ key: SPRING_DATASOURCE_USERNAME
+ - name: MYSQL_DATABASE
+ valueFrom:
+ configMapKeyRef:
+ name: bankapp-config
+ key: MYSQL_DATABASE
+ - name: SPRING_DATASOURCE_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: mysql-secret
+ key: SPRING_DATASOURCE_PASSWORD
+ # readinessProbe:
+ # httpGet:
+ # path: /actuator/health # Update this based on your app's health endpoint
+ # port: 8080
+ # initialDelaySeconds: 10
+ # periodSeconds: 5
+ # livenessProbe:
+ # httpGet:
+ # path: /actuator/health # Update this based on your app's health endpoint
+ # port: 8080
+ # initialDelaySeconds: 30
+ # periodSeconds: 10
+ resources:
+ requests:
+ memory: "512Mi"
+ cpu: "250m"
+ limits:
+ memory: "1Gi"
+ cpu: "500m"
diff --git a/kubernetes/bankapp-hpa.yml b/kubernetes/bankapp-hpa.yml
new file mode 100644
index 00000000..6c030161
--- /dev/null
+++ b/kubernetes/bankapp-hpa.yml
@@ -0,0 +1,19 @@
+apiVersion: autoscaling/v2
+kind: HorizontalPodAutoscaler
+metadata:
+ name: bankapp-hpa
+ namespace: bankapp-namespace
+spec:
+ scaleTargetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: bankapp-deploy
+ minReplicas: 1
+ maxReplicas: 5
+ metrics:
+ - type: Resource
+ resource:
+ name: cpu
+ target:
+ type: Utilization
+ averageUtilization: 40
diff --git a/kubernetes/bankapp-ingress.yml b/kubernetes/bankapp-ingress.yml
new file mode 100644
index 00000000..528d9e07
--- /dev/null
+++ b/kubernetes/bankapp-ingress.yml
@@ -0,0 +1,28 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+
+metadata:
+ name: bankapp-ingress
+ namespace: bankapp-namespace
+ annotations:
+ nginx.ingress.kubernetes.io/rewrite-target: /
+ nginx.ingress.kubernetes.io/proxy-body-size: "50m"
+ nginx.ingress.kubernetes.io/ssl-redirect: "true" # Force HTTPS
+ cert-manager.io/cluster-issuer: letsencrypt-prod # Use Let's Encrypt
+spec:
+ ingressClassName: nginx
+ tls:
+ - hosts:
+ - himanshibankapp.duckdns.org
+ secretName: bankapp-tls-secret
+ rules:
+ - host: himanshibankapp.duckdns.org
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: bankapp-service
+ port:
+ number: 8080
diff --git a/kubernetes/bankapp-namespace.yml b/kubernetes/bankapp-namespace.yml
new file mode 100644
index 00000000..d90656c1
--- /dev/null
+++ b/kubernetes/bankapp-namespace.yml
@@ -0,0 +1,6 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: bankapp-namespace
+ labels:
+ name: bankapp-namespace
\ No newline at end of file
diff --git a/kubernetes/bankapp-service.yml b/kubernetes/bankapp-service.yml
new file mode 100644
index 00000000..b09014a6
--- /dev/null
+++ b/kubernetes/bankapp-service.yml
@@ -0,0 +1,16 @@
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: bankapp-service
+ namespace: bankapp-namespace
+ labels:
+ app: bankapp
+spec:
+ selector:
+ app: bankapp-deploy
+ ports:
+ - protocol: TCP
+ port: 8080
+ targetPort: 8080
+
diff --git a/kubernetes/cert-issuer.yml b/kubernetes/cert-issuer.yml
new file mode 100644
index 00000000..433992f0
--- /dev/null
+++ b/kubernetes/cert-issuer.yml
@@ -0,0 +1,16 @@
+apiVersion: cert-manager.io/v1
+kind: ClusterIssuer
+
+metadata:
+ name: letsencrypt-prod
+
+spec:
+ acme:
+ server: https://acme-v02.api.letsencrypt.org/directory
+ email: himanshibobde@gmail.com
+ privateKeySecretRef:
+ name: letsencrypt-prod-key
+ solvers:
+ - http01:
+ ingress:
+ class: nginx
diff --git a/kubernetes/configmap.yml b/kubernetes/configmap.yml
new file mode 100644
index 00000000..67fd1ef4
--- /dev/null
+++ b/kubernetes/configmap.yml
@@ -0,0 +1,10 @@
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: bankapp-config
+ namespace: bankapp-namespace
+data:
+ MYSQL_DATABASE: BankDB
+ SPRING_DATASOURCE_URL: jdbc:mysql://mysql-svc.bankapp-namespace.svc.cluster.local:3306/BankDB?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
+ SPRING_DATASOURCE_USERNAME: root
diff --git a/kubernetes/mysql-deployment.yml b/kubernetes/mysql-deployment.yml
new file mode 100644
index 00000000..8c0e3965
--- /dev/null
+++ b/kubernetes/mysql-deployment.yml
@@ -0,0 +1,41 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: mysql
+ namespace: bankapp-namespace
+ labels:
+ app: mysql
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: mysql
+ template:
+ metadata:
+ labels:
+ app: mysql
+ spec:
+ containers:
+ - name: mysql
+ image: mysql:8.0 # Use a specific, stable version for production
+ ports:
+ - containerPort: 3306
+ env:
+ - name: MYSQL_ROOT_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: mysql-secret
+ key: MYSQL_ROOT_PASSWORD
+ - name: MYSQL_DATABASE
+ valueFrom:
+ configMapKeyRef:
+ name: bankapp-config
+ key: MYSQL_DATABASE
+ volumeMounts:
+ - name: mysql-pv-storage
+ mountPath: /var/lib/mysql
+ subPath: mysql-data # Optional: Ensure a subdirectory is used for better volume organization
+ volumes:
+ - name: mysql-pv-storage
+ persistentVolumeClaim:
+ claimName: mysql-pvc
\ No newline at end of file
diff --git a/kubernetes/mysql-service.yml b/kubernetes/mysql-service.yml
new file mode 100644
index 00000000..8a46c496
--- /dev/null
+++ b/kubernetes/mysql-service.yml
@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: mysql-svc
+ namespace: bankapp-namespace
+ labels:
+ app: mysql
+spec:
+ selector:
+ app: mysql
+ ports:
+ - protocol: TCP
+ port: 3306
+ targetPort: 3306
\ No newline at end of file
diff --git a/kubernetes/persistent-volume-claim.yml b/kubernetes/persistent-volume-claim.yml
new file mode 100644
index 00000000..ec47c52f
--- /dev/null
+++ b/kubernetes/persistent-volume-claim.yml
@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: mysql-pvc
+ namespace: bankapp-namespace
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 10Gi
+ storageClassName: standard
\ No newline at end of file
diff --git a/kubernetes/persistent-volume.yml b/kubernetes/persistent-volume.yml
new file mode 100644
index 00000000..6d56f7cf
--- /dev/null
+++ b/kubernetes/persistent-volume.yml
@@ -0,0 +1,16 @@
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+ name: mysql-pv
+ namespace: bankapp-namespace
+spec:
+ capacity:
+ storage: 10Gi
+ volumeMode: Filesystem
+ accessModes:
+ - ReadWriteOnce
+ persistentVolumeReclaimPolicy: Retain # Keeps the PV after the PVC is deleted
+ storageClassName: standard # Make sure this matches your cluster's default storage class
+ hostPath:
+ path: /mnt/data/mysql
+ type: DirectoryOrCreate
\ No newline at end of file
diff --git a/kubernetes/secrets.yml b/kubernetes/secrets.yml
new file mode 100644
index 00000000..a0642661
--- /dev/null
+++ b/kubernetes/secrets.yml
@@ -0,0 +1,10 @@
+apiVersion: v1
+kind: Secret
+metadata:
+ name: mysql-secret
+ namespace: bankapp-namespace
+type: Opaque
+data:
+ MYSQL_ROOT_PASSWORD: VGVzdEAxMjM= # Base64 for "Test@123"
+ SPRING_DATASOURCE_PASSWORD: VGVzdEAxMjM= # Base64 for "Test@123"
+
\ No newline at end of file
diff --git a/terraform/Ec2.tf b/terraform/Ec2.tf
new file mode 100644
index 00000000..72b321fa
--- /dev/null
+++ b/terraform/Ec2.tf
@@ -0,0 +1,77 @@
+data "aws_ami" "os_image" {
+ owners = ["099720109477"]
+ most_recent = true
+ filter {
+ name = "state"
+ values = ["available"]
+ }
+ filter {
+ name = "name"
+ values = ["ubuntu/images/hvm-ssd/*amd64*"]
+ }
+}
+
+resource "aws_key_pair" "deployer" {
+ key_name = "bankapp-automate-key"
+ public_key = file("bankapp-automate-key.pub")
+}
+
+resource "aws_default_vpc" "default" {
+
+}
+
+resource "aws_security_group" "allow_user_to_connect" {
+ name = "allow TLS"
+ description = "Allow user to connect"
+ vpc_id = aws_default_vpc.default.id
+ ingress {
+ description = "port 22 allow ssh"
+ from_port = 22
+ to_port = 22
+ protocol = "tcp"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+
+ egress {
+ description = " allow all outgoing traffic "
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+
+ ingress {
+ description = "port 80 allow http"
+ from_port = 80
+ to_port = 80
+ protocol = "tcp"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+
+ ingress {
+ description = "port 443 allow https"
+ from_port = 443
+ to_port = 443
+ protocol = "tcp"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+
+ tags = {
+ Name = "bankapp_security"
+ }
+}
+
+resource "aws_instance" "testinstance" {
+ ami = data.aws_ami.os_image.id
+ instance_type = var.my_enviroment == "prd" ? "t2.medium" : "t2.micro"
+ key_name = aws_key_pair.deployer.key_name
+ security_groups = [aws_security_group.allow_user_to_connect.name]
+ tags = {
+ Name = "BankApp_Automation_Server"
+ }
+ root_block_device {
+ volume_size = 30
+ volume_type = "gp3"
+ }
+
+}
\ No newline at end of file
diff --git a/terraform/bankapp-automate-key.pub b/terraform/bankapp-automate-key.pub
new file mode 100644
index 00000000..3a3d5466
--- /dev/null
+++ b/terraform/bankapp-automate-key.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDBFC8bY7ZvV+2qbosgZ7P4IDJnjLZmd4J4TdnKmitZ9 himan@Himanshi
diff --git a/terraform/main.tf b/terraform/main.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/terraform/terraform.tf b/terraform/terraform.tf
new file mode 100644
index 00000000..6c128499
--- /dev/null
+++ b/terraform/terraform.tf
@@ -0,0 +1,13 @@
+terraform {
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "6.13.0"
+ }
+ }
+}
+
+provider "aws" {
+ # Configuration options
+ region = var.aws_region
+}
\ No newline at end of file
diff --git a/terraform/utputs.tf b/terraform/utputs.tf
new file mode 100644
index 00000000..e1b4e4fe
--- /dev/null
+++ b/terraform/utputs.tf
@@ -0,0 +1,7 @@
+output "arn" {
+ value = aws_instance.testinstance.arn
+}
+
+output "public_ip" {
+ value = aws_instance.testinstance.public_ip
+}
\ No newline at end of file
diff --git a/terraform/variables.tf b/terraform/variables.tf
new file mode 100644
index 00000000..2c6bd730
--- /dev/null
+++ b/terraform/variables.tf
@@ -0,0 +1,19 @@
+variable "aws_region" {
+ description = "AWS region where resources will be provisioned"
+ default = "us-east-1"
+}
+
+variable "ami_id" {
+ description = "AMI ID for the EC2 instance"
+ default = "ami-085f9c64a9b75eed5"
+}
+
+variable "instance_type" {
+ description = "Instance type for the EC2 instance"
+ default = "t2.large"
+}
+
+variable "my_enviroment" {
+ description = "Instance type for the EC2 instance"
+ default = "dev"
+}
\ No newline at end of file