Skip to content

prajwalchapke055/Amazon-Prime-Clone-DevSecOps-Project

Repository files navigation

Amazon Prime Clone Deployment Project

Pipeline Overview


Project Overview

This project demonstrates deploying an Amazon Prime clone using a set of DevOps tools and practices. The primary tools include:

Tool Purpose
Git Version control system to manage source code.
GitHub Source code hosting and collaboration platform.
Visual Studio Code Lightweight and powerful code editor for development.
AWS IAM Identity and Access Management for AWS services and user roles.
Terraform Infrastructure as Code (IaC) tool to provision AWS resources like EC2 and EKS.
Jenkins CI/CD automation tool for building, testing, and deploying applications.
SonarQube Code quality analysis and static code inspection with quality gates.
NPM Node.js package manager used for building and managing dependencies.
OWASP Dependency-Check Detect known vulnerabilities in project dependencies.
Aqua Trivy Security scanner for vulnerabilities in Docker images and Kubernetes.
Docker Containerization tool for creating and managing container images.
Docker Hub Cloud-based Docker registry for storing and sharing container images.
AWS ECR Private container registry on AWS for Docker images.
AWS EKS Kubernetes-based container orchestration service by AWS.
Helm Kubernetes package manager for deploying applications (charts).
ArgoCD GitOps-based continuous delivery tool for Kubernetes.
Prometheus Monitoring system and time-series database for metrics.
Grafana Visualization and alerting dashboard for Prometheus metrics.
Blackbox Exporter Probes endpoints (HTTP, TCP, etc.) and exposes metrics for Prometheus.

Pre-requisites

  1. AWS Account: Ensure you have an AWS account. Create an AWS Account
  2. AWS CLI: Install AWS CLI on your local machine. AWS CLI Installation Guide
  3. VS Code (Optional): Download and install VS Code as a code editor. VS Code Download
  4. Install Terraform in Windows: Download and install Terraform in Windows Terraform in Windows

Note For Developers

  • This project is a Amazon Prime Clone. You can run the below commands to see the project on your local system.

  • Hosted on Firebase at - https://prime-clone-2fcfe.web.app/ (Desktop View Only). For getting Data I have used TMDB API.

  • For running the App locally you will have to generate your own API_Key and substitute in all requests files and App.js files.

  • You can check out other ReactJs projects as well in other repositories deployed on firebase.

  • Icons from Material UI library have been used. Link is - https://material-ui.com/components/material-icons/

Technologies Used:

  • ReactJS
  • NodeJS
  • MaterialUI for icons

Note: Don't use it for any commercial purposes.


Configuration

AWS Setup

  1. IAM User: Create an IAM user and generate the access and secret keys to configure your machine with AWS.
  2. Key Pair: Create a key pair named key for accessing your EC2 instances.

Infrastructure Setup Using Terraform

  1. Clone the Repository (Open Command Prompt & run below):
    git clone https://github.com/prajwalchapke055/Amazon-Prime-Clone-DevSecOps-Project.git
    cd Amazon-Prime-Clone-DevSecOps-Project
    code .   # this command will open VS code in backend
  2. Initialize and Apply Terraform:
    • Run the below commands to reduce the path displayed in VS Code terminal (Optional)
      code $PROFILE
      function prompt {"$PWD > "}
      function prompt {$(Get-Location -Leaf) + " > "}
    • Open terraform_code/ec2_server/main.tf in VS Code.
    • Run the following commands:
      aws configure
      terraform init
      terraform apply --auto-approve

This will create the EC2 instance, security groups, and install necessary tools like Jenkins, Docker, SonarQube, etc.


SonarQube Configuration

  1. Login Credentials: Use admin for both username and password.
  2. Generate SonarQube Token:
    • Create a token under Administration → Security → Users → Tokens.
    • Save the token for integration with Jenkins.

Jenkins Configuration

  1. Add Jenkins Credentials:

    • Add the SonarQube token, AWS access key, and secret key in Manage Jenkins → Credentials → System → Global credentials.
  2. Install Required Plugins:

    • Install plugins such as SonarQube Scanner, NodeJS, Docker, and Prometheus metrics under Manage Jenkins → Plugins.
  3. Global Tool Configuration:

    • Set up tools like JDK 17, SonarQube Scanner, NodeJS, and Docker under Manage Jenkins → Global Tool Configuration.

Pipeline Overview

Pipeline Stages

  1. Clean Workspace – Clears previous build artifacts and resets the Jenkins workspace.
  2. Git Checkout – Clones the latest source code from the GitHub repository.
  3. SonarQube Code Analysis – Performs static code analysis for bugs, vulnerabilities, and code smells.
  4. Quality Gate Validation – Verifies that the SonarQube quality gate status is acceptable before proceeding.
  5. Install NPM Dependencies – Installs Node.js dependencies with npm install.
  6. OWASP Dependency-Check – Scans project dependencies for known security vulnerabilities using OWASP (if enabled).
  7. Trivy Security Scan – Runs Trivy to detect file-system-level vulnerabilities and outputs an HTML report.
  8. Docker Image Build & Local Run – Builds the Docker image and runs it locally to verify functionality.
  9. Create AWS ECR Repository – Creates the specified ECR repository if it doesn’t already exist.
  10. Authenticate with AWS ECR – Logs in to AWS ECR using AWS credentials for pushing images.
  11. Push Docker Image to AWS ECR – Pushes Docker images with versioned and latest tags to ECR.
  12. Cleanup Local Docker Images – Removes local Docker containers and images to save disk space.
  13. Post-Build Email Notification – Sends an HTML email with build result, reports, and pipeline summary.

Running Jenkins Pipeline

Create and run the build pipeline in Jenkins. The pipeline will build, analyze, and push the project Docker image to ECR. Create a Jenkins pipeline by adding the following script:


Build Pipeline

pipeline {
    agent any

    parameters {
        string(name: 'ECR_REPO_NAME', defaultValue: 'amazon-prime', description: 'Enter repository name')
        string(name: 'AWS_ACCOUNT_ID', defaultValue: '123456789012', description: 'Enter AWS Account ID')
    }

    tools {
        jdk 'JDK17'
        nodejs 'NodeJS'
    }

    environment {
        SCANNER_HOME = tool 'SonarQube Scanner'
        AWS_REGION = "us-east-1"
        IMAGE_NAME = "${params.ECR_REPO_NAME}"
        ECR_URI = "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${params.ECR_REPO_NAME}"
    }

    stages {

        stage ('1. Clean Workspace') {
            steps {
                cleanWs()
            }
        }

        stage('2. Git Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/prajwalchapke055/Amazon-Prime-Clone-DevSecOps-Project.git'
            }
        }

        stage('3. SonarQube Analysis') {
            steps {
                withSonarQubeEnv('sonar-server') {
                    sh """
                    ${SCANNER_HOME}/bin/sonar-scanner \
                    -Dsonar.projectName=amazon-prime \
                    -Dsonar.projectKey=amazon-prime
                    """
                }
            }
        }

        // stage('4. Quality Gate') {
        //   steps {
        //        waitForQualityGate abortPipeline: true
        //    }
        // }

        stage("4. Quality Gate") {
            steps {
                script {
                    def qualityGate = waitForQualityGate(abortPipeline: false, credentialsId: 'sonar-token')
                    if (qualityGate.status != 'OK') {
                        error "Quality Gate failed: ${qualityGate.status}"
                        }
                    }
                }
        }


        stage('5. Install NPM Dependencies') {
            steps {
                sh '''
                rm -rf node_modules package-lock.json
                npm install --legacy-peer-deps
                '''
            }
        }

// stage('6. OWASP Dependency-Check') {
//     steps {
//         withCredentials([string(credentialsId: 'nvd-api-key', variable: 'NVD_API_KEY')]) {
//             sh 'mkdir -p dependency-check-report'  // Ensure output directory exists
//             dependencyCheck(
//                 additionalArguments: '--scan ./ ' +
//                                      '--format XML ' +
//                                      '--format HTML ' +
//                                      '--out dependency-check-report ' +
//                                      '--disableYarnAudit ' +
//                                      '--disableNodeAudit ' +
//                                      '--nvdApiKey=' + NVD_API_KEY,
//                 odcInstallation: 'dc'
//             )
//         }
//         dependencyCheckPublisher pattern: '**/dependency-check-report.xml'
//     }
// }


        stage('6. Trivy Scan & Report') {
            steps {
                script {
                    sh "trivy fs --format table -o trivy-fs-report.html . "
                }
            }
        }
        
stage('7. Build Docker Image') {
            steps {
                script {
                    sh """
                        echo "Cleaning up any existing containers..."

                        # Stop and remove running container
                        if docker ps -a --format '{{.Names}}' | grep -w amazon-prime; then
                            docker stop amazon-prime || true
                            docker rm -f amazon-prime || true
                        fi

                        # Remove image if exists
                        if docker images -q ${IMAGE_NAME}:latest > /dev/null; then
                            docker rmi -f ${IMAGE_NAME}:latest || true
                        fi

                        echo "Building new Docker image..."
                        docker build -t ${IMAGE_NAME}:latest .

                        echo "Tagging image for ECR..."
                        docker tag ${IMAGE_NAME}:latest ${ECR_URI}:${BUILD_NUMBER}
                        docker tag ${IMAGE_NAME}:latest ${ECR_URI}:latest

                        echo "Running container on port 5000..."
                        docker run -d --name amazon-prime -p 5000:5000 ${IMAGE_NAME}:latest
                    """
                }
            }
        }

        stage('8. Create ECR Repo') {
            steps {
                withCredentials([
                    string(credentialsId: 'access-key', variable: 'AWS_ACCESS_KEY'),
                    string(credentialsId: 'secret-key', variable: 'AWS_SECRET_KEY')
                ]) {
                    sh """
                        aws configure set aws_access_key_id $AWS_ACCESS_KEY
                        aws configure set aws_secret_access_key $AWS_SECRET_KEY
                        aws ecr describe-repositories --repository-names ${IMAGE_NAME} --region ${AWS_REGION} || \
                        aws ecr create-repository --repository-name ${IMAGE_NAME} --region ${AWS_REGION}
                    """
                }
            }
        }

        stage('9. Login to ECR') {
            steps {
                withCredentials([
                    string(credentialsId: 'access-key', variable: 'AWS_ACCESS_KEY'),
                    string(credentialsId: 'secret-key', variable: 'AWS_SECRET_KEY')
                ]) {
                    sh """
                        aws configure set aws_access_key_id $AWS_ACCESS_KEY
                        aws configure set aws_secret_access_key $AWS_SECRET_KEY
                        aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${ECR_URI}
                    """
                }
            }
        }

        stage('10. Push Image to ECR') {
            steps {
                sh """
                    docker push ${ECR_URI}:${BUILD_NUMBER}
                    docker push ${ECR_URI}:latest
                """
            }
        }

        stage('11. Cleanup Old Images') {
            steps {
                sh """
                    docker rmi -f ${ECR_URI}:${BUILD_NUMBER} || true
                    docker rmi -f ${ECR_URI}:latest || true
                    docker rmi -f ${IMAGE_NAME}:latest || true
                    docker image prune -f
                """
            }
        }
    }
    
    
post {
    always {
        // archiveArtifacts artifacts: 'dependency-check-report/*', fingerprint: true

        script {
            def jobName = env.JOB_NAME
            def buildNumber = env.BUILD_NUMBER
            def buildStatus = currentBuild.currentResult ?: 'UNKNOWN'

            def userCause = currentBuild.getBuildCauses('hudson.model.Cause$UserIdCause')
            def buildUser = userCause ? userCause[0]?.userId : 'GitHub or Timer Triggered'

            def bannerColor = buildStatus.toUpperCase() == 'SUCCESS' ? 'green' : 'red'

            def body = """<html>
                            <body>
                                <div style="border: 4px solid ${bannerColor}; padding: 10px;">
                                    <h2>${jobName} - Build #${buildNumber}</h2>
                                    <div style="background-color: ${bannerColor}; padding: 10px;">
                                        <h3 style="color: white;">Pipeline Status: ${buildStatus.toUpperCase()}</h3>
                                    </div>
                                    <p><strong>Started by:</strong> ${buildUser}</p>
                                    <p>Check the <a href="${env.BUILD_URL}">console output</a>.</p>
                                </div>
                            </body>
                          </html>"""

            emailext(
                subject: "Pipeline ${buildStatus}: ${jobName} #${buildNumber}",
                body: body,
                to: 'prajwalchapke742@gmail.com',
                from: 'prajwalchapke742@gmail.com',
                replyTo: 'prajwalchapke742@gmail.com',
                mimeType: 'text/html',
                attachmentsPattern: 'trivy-fs-report.html,dependency-check-report.xml,**/*.html,**/*txt,**/*.xml'
            	)
        	}
	}
}
}

Continuous Deployment with ArgoCD

  1. Create EKS Cluster: Use Terraform to create an EKS cluster and related resources.
  2. Deploy Amazon Prime Clone: Use ArgoCD to deploy the application using Kubernetes YAML files.
  3. Monitoring Setup: Install Prometheus and Grafana using Helm charts for monitoring the Kubernetes cluster.

Deployment Pipeline

pipeline {
    agent any

    environment {
        KUBECTL = '/usr/local/bin/kubectl'
    }

    parameters {
        string(name: 'AWS_REGION', defaultValue: 'us-east-1', description: 'Enter your AWS region')
        string(name: 'AWS_ACCOUNT_ID', defaultValue: '123456789000', description: 'Enter your AWS account ID')
        string(name: 'ECR_REPO_NAME', defaultValue: 'amazon-prime', description: 'Enter ECR repository name')
        string(name: 'VERSION', defaultValue: 'latest', description: 'Enter image version tag')
        string(name: 'CLUSTER_NAME', defaultValue: 'amazon-prime-cluster', description: 'Enter your EKS cluster name')
    }

    stages {

        stage("1. Clone GitHub Repository") {
            steps {
                git branch: 'main', url: 'https://github.com/prajwalchapke055/Amazon-Prime-Clone-DevSecOps-Project.git'
            }
        }

        stage("2. Login to EKS") {
            steps {
                script {
                    withCredentials([
                        string(credentialsId: 'access-key', variable: 'AWS_ACCESS_KEY'),
                        string(credentialsId: 'secret-key', variable: 'AWS_SECRET_KEY')
                    ]) {
                        sh """
                        aws configure set aws_access_key_id $AWS_ACCESS_KEY
                        aws configure set aws_secret_access_key $AWS_SECRET_KEY
                        aws configure set region ${params.AWS_REGION}
                        aws eks --region ${params.AWS_REGION} update-kubeconfig --name ${params.CLUSTER_NAME}
                        """
                    }
                }
            }
        }

        stage("3. Configure Prometheus & Grafana") {
            steps {
                script {
                    sh """
                    helm repo add stable https://charts.helm.sh/stable || true
                    helm repo add prometheus-community https://prometheus-community.github.io/helm-charts || true

                    if kubectl get namespace prometheus > /dev/null 2>&1; then
                        helm upgrade stable prometheus-community/kube-prometheus-stack -n prometheus
                    else
                        kubectl create namespace prometheus
                        helm install stable prometheus-community/kube-prometheus-stack -n prometheus
                    fi

                    kubectl patch svc stable-kube-prometheus-sta-prometheus -n prometheus -p '{"spec": {"type": "LoadBalancer"}}'
                    kubectl patch svc stable-grafana -n prometheus -p '{"spec": {"type": "LoadBalancer"}}'
                    """
                }
            }
        }

        stage("4. Configure ArgoCD") {
            steps {
                script {
                    sh """
                    kubectl create namespace argocd || true
                    kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
                    kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
                    """
                }
            }
        }

        stage("5. Update Image in manifest.yml") {
            steps {
                script {
                    def IMAGE = "${params.AWS_ACCOUNT_ID}.dkr.ecr.${params.AWS_REGION}.amazonaws.com/${params.ECR_REPO_NAME}:${params.VERSION}"
                    sh "sed -i 's|image: .*|image: ${IMAGE}|' k8s_files/manifest.yml"
                }
            }
        }

        stage("6. Deploy Application to EKS") {
            steps {
                script {
                    // Apply single manifest
                    sh "kubectl apply -f k8s_files/manifest.yml"
                }
            }
        }
    }
}

Screenshots of Website

Screenshot (288)

Screenshot (289)


Cleanup

  • Run cleanup pipelines to delete the resources such as load balancers, services, and deployment files.
  • Use terraform destroy to remove the EKS cluster and other infrastructure.

Cleanup Pipeline

pipeline {
    agent any

    environment {
        KUBECTL = '/usr/local/bin/kubectl'
    }

    parameters {
        string(name: 'CLUSTER_NAME', defaultValue: 'amazon-prime-cluster', description: 'Enter your EKS cluster name')
    }

    stages {

        stage("1. Login to EKS") {
            steps {
                script {
                    withCredentials([string(credentialsId: 'access-key', variable: 'AWS_ACCESS_KEY'),
                                     string(credentialsId: 'secret-key', variable: 'AWS_SECRET_KEY')]) {
                        sh "aws eks --region us-east-1 update-kubeconfig --name ${params.CLUSTER_NAME}"
                    }
                }
            }
        }
        
        stage('2. Cleanup K8s Resources') {
            steps {
                script {
                    // Step 1: Delete services and deployments
                    sh 'kubectl delete svc kubernetes || true'
                    sh 'kubectl delete deploy pandacloud-app || true'
                    sh 'kubectl delete svc pandacloud-app || true'

                    // Step 2: Delete ArgoCD installation and namespace
                    sh 'kubectl delete -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml || true'
                    sh 'kubectl delete namespace argocd || true'

                    // Step 3: List and uninstall Helm releases in prometheus namespace
                    sh 'helm list -n prometheus || true'
                    sh 'helm uninstall kube-stack -n prometheus || true'
                    
                    // Step 4: Delete prometheus namespace
                    sh 'kubectl delete namespace prometheus || true'

                    // Step 5: Remove Helm repositories
                    sh 'helm repo remove stable || true'
                    sh 'helm repo remove prometheus-community || true'
                }
            }
        }
		
        stage('3. Delete ECR Repository and KMS Keys') {
            steps {
                script {
                    // Step 1: Delete ECR Repository
                    sh '''
                    aws ecr delete-repository --repository-name amazon-prime --region us-east-1 --force
                    '''

                    // Step 2: Delete KMS Keys
                    sh '''
                    for key in $(aws kms list-keys --region us-east-1 --query "Keys[*].KeyId" --output text); do
                        aws kms disable-key --key-id $key --region us-east-1
                        aws kms schedule-key-deletion --key-id $key --pending-window-in-days 7 --region us-east-1
                    done
                    '''
                }
            }
        }		
		
    }
}

Additional Information

For further details, refer to the word document containing a complete write-up of the project.

Available Scripts

In this project directory, you can run:

npm install

This command installs all the required dependencies for running the App.

npm start

Runs the app in the development mode.

Open http://localhost:5000 to view it in the browser. 

The page will reload if you make edits. You will also see any lint errors in the console.


About

This project automates the deployment of an Amazon Prime Clone using GitHub, Jenkins, SonarQube, Trivy, and Docker. Terraform provisions AWS infrastructure, Helm and ArgoCD handle deployments to AWS EKS, and Prometheus with Grafana enables monitoring. It demonstrates a complete CI/CD pipeline with security, scalability, and real-time monitoring.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors