diff --git a/.github/SECRETS.md b/.github/SECRETS.md new file mode 100644 index 00000000..19164443 --- /dev/null +++ b/.github/SECRETS.md @@ -0,0 +1,29 @@ +# Required GitHub Actions Secrets + +The following secrets must be configured in the repository settings: + +## Docker Hub +- `DOCKERHUB_USERNAME`: Docker Hub username (madhupdevops) +- `DOCKERHUB_TOKEN`: Docker Hub access token + +## SonarQube +- `SONAR_TOKEN`: SonarQube authentication token +- `SONAR_HOST_URL`: SonarQube server URL + +## Email Notifications +- `EMAIL_USERNAME`: SMTP username for notifications +- `EMAIL_PASSWORD`: SMTP password for notifications +- `EMAIL_TO`: Recipient email address +- `EMAIL_FROM`: Sender email address + +## Setup Instructions +1. Go to repository Settings > Secrets and variables > Actions +2. Add each secret with the corresponding value +3. Ensure the GitHub token has write permissions for repository dispatch + +## Migration Notes +These secrets replace the Jenkins credentials that were previously used: +- Jenkins `docker` credential → `DOCKERHUB_USERNAME` + `DOCKERHUB_TOKEN` +- Jenkins `Github-cred` credential → Built-in `GITHUB_TOKEN` +- Jenkins SonarQube configuration → `SONAR_TOKEN` + `SONAR_HOST_URL` +- Jenkins email configuration → Email secrets above diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 00000000..3d18f778 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,77 @@ +name: CD Pipeline (GitOps) + +on: + repository_dispatch: + types: [ci-complete] + workflow_dispatch: + inputs: + docker_tag: + description: 'Docker tag to deploy' + required: true + +env: + DOCKER_TAG: ${{ github.event.client_payload.docker_tag || github.event.inputs.docker_tag }} + +jobs: + cd: + runs-on: ubuntu-latest + + steps: + - name: Workspace cleanup + run: | + sudo rm -rf $GITHUB_WORKSPACE/* + sudo rm -rf $GITHUB_WORKSPACE/.[!.]* + + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: DevOps + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Verify Docker tag + run: | + echo "DOCKER TAG RECEIVED: ${{ env.DOCKER_TAG }}" + + - name: Update Kubernetes manifest + run: | + cd kubernetes + sed -i -e 's|trainwithshubham/bankapp-eks:.*|trainwithshubham/bankapp-eks:${{ env.DOCKER_TAG }}|g' bankapp-deployment.yml + + - name: Commit and push changes + run: | + git config --local user.email "devin-ai-integration[bot]@users.noreply.github.com" + git config --local user.name "Devin AI" + echo "Checking repository status: " + git status + echo "Adding changes to git: " + git add . + echo "Commiting changes: " + git commit -m "Updated K8s Deployment Docker Image Version to ${{ env.DOCKER_TAG }}" + echo "Pushing changes to github: " + git push origin DevOps + + - name: Send notification email + uses: dawidd6/action-send-mail@v3 + if: always() + with: + server_address: smtp.gmail.com + server_port: 587 + username: ${{ secrets.EMAIL_USERNAME }} + password: ${{ secrets.EMAIL_PASSWORD }} + subject: "BankApp Application has been updated and deployed - ${{ job.status }}" + to: ${{ secrets.EMAIL_TO }} + from: ${{ secrets.EMAIL_FROM }} + html_body: | + + +
+

Project: ${{ github.repository }}

+
+
+

Build Number: ${{ github.run_number }}

+
+
+

URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

+
+ + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..b1a6778d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,128 @@ +name: CI Pipeline + +on: + push: + branches: [ DevOps, main ] + pull_request: + branches: [ DevOps, main ] + workflow_dispatch: + inputs: + docker_tag: + description: 'Docker tag for the image' + required: true + default: 'latest' + +env: + DOCKER_TAG: ${{ github.event.inputs.docker_tag || github.sha }} + DOCKERHUB_USERNAME: madhupdevops + PROJECT_NAME: bankapp + +jobs: + ci: + runs-on: ubuntu-latest + + steps: + - name: Workspace cleanup + run: | + sudo rm -rf $GITHUB_WORKSPACE/* + sudo rm -rf $GITHUB_WORKSPACE/.[!.]* + + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: DevOps + + - name: Set up Java + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + - name: Install Trivy + run: | + sudo apt-get update + sudo apt-get install wget apt-transport-https gnupg lsb-release + wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add - + echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list.d/trivy.list + sudo apt-get update + sudo apt-get install trivy + + - name: Trivy filesystem scan + run: | + trivy fs . + continue-on-error: true + + - name: OWASP Dependency Check + uses: dependency-check/Dependency-Check_Action@main + with: + project: 'bankapp' + path: '.' + format: 'XML' + out: 'reports' + continue-on-error: true + + - name: Upload OWASP results + uses: actions/upload-artifact@v4 + if: always() + with: + name: dependency-check-report + path: reports/dependency-check-report.xml + + - name: Install SonarQube Scanner + run: | + wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.8.0.2856-linux.zip + unzip sonar-scanner-cli-4.8.0.2856-linux.zip + sudo mv sonar-scanner-4.8.0.2856-linux /opt/sonar-scanner + sudo ln -s /opt/sonar-scanner/bin/sonar-scanner /usr/local/bin/sonar-scanner + + - name: SonarQube analysis + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + run: | + sonar-scanner \ + -Dsonar.projectKey=bankapp \ + -Dsonar.projectName=bankapp \ + -Dsonar.sources=. \ + -Dsonar.host.url=${{ secrets.SONAR_HOST_URL }} \ + -Dsonar.login=${{ secrets.SONAR_TOKEN }} \ + -X + continue-on-error: true + + - name: SonarQube Quality Gate + uses: sonarqube-quality-gate-action@master + timeout-minutes: 1 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + continue-on-error: true + + - name: Docker build + run: | + docker build -t ${{ env.DOCKERHUB_USERNAME }}/${{ env.PROJECT_NAME }}:${{ env.DOCKER_TAG }} . + + - name: Docker login + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Docker push + run: | + docker push ${{ env.DOCKERHUB_USERNAME }}/${{ env.PROJECT_NAME }}:${{ env.DOCKER_TAG }} + + - name: Archive artifacts + uses: actions/upload-artifact@v4 + if: always() + with: + name: build-artifacts + path: | + reports/*.xml + *.xml + + - name: Trigger CD workflow + if: success() + uses: peter-evans/repository-dispatch@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + event-type: ci-complete + client-payload: '{"docker_tag": "${{ env.DOCKER_TAG }}"}' diff --git a/README.md b/README.md index 2f49958e..fcef28b5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,43 @@ ## End-to-End Bank Application Deployment using DevSecOps on AWS EKS -- This is a multi-tier bank an application written in Java (Springboot). +- This is a multi-tier bank application written in Java (Springboot). + +## Migration from Jenkins to GitHub Actions + +This repository has been migrated from Jenkins-based CI/CD to GitHub Actions workflows. The legacy Jenkins configuration files are preserved in the `legacy/jenkins/` directory for reference. + +### GitHub Actions Workflows + +The CI/CD pipeline now consists of two main GitHub Actions workflows: + +#### CI Pipeline (`.github/workflows/ci.yml`) +1. **Code Checkout**: Retrieves source code from GitHub +2. **Java Setup**: Configures Java 17 environment +3. **Security Scanning**: + - Trivy filesystem scan for vulnerabilities + - OWASP dependency check for known security issues +4. **Code Quality**: SonarQube analysis with quality gates +5. **Container Operations**: Docker image build and push to registry +6. **Trigger CD**: Initiates the GitOps deployment workflow + +#### CD Pipeline (`.github/workflows/cd.yml`) +1. **Manifest Updates**: Updates Kubernetes deployment manifests with new image tags +2. **GitOps Commit**: Commits and pushes changes to trigger ArgoCD synchronization +3. **Notifications**: Sends email notifications about deployment status + +### Required Secrets + +See `.github/SECRETS.md` for the complete list of required repository secrets for Docker Hub, SonarQube, and email notifications. + +### Setup Instructions + +1. **Configure GitHub Actions Secrets**: + - Follow the instructions in `.github/SECRETS.md` + - Add all required secrets to repository settings + +2. **Pipeline Execution**: + - Push changes to the `DevOps` branch to trigger CI pipeline + - Use workflow dispatch to manually trigger builds with custom Docker tags + - CD pipeline automatically triggers after successful CI builds ![Login diagram](images/login.png) ![Transactions diagram](images/transactions.png) @@ -86,33 +124,15 @@ sudo su ``` > [!Note] > Make sure the ssh-public-key "eks-nodegroup-key is available in your aws account" -- Install Jenkins -```bash -sudo apt update -y -sudo apt install fontconfig openjdk-17-jre -y - -sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \ - https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key - -echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]" \ - https://pkg.jenkins.io/debian-stable binary/ | sudo tee \ - /etc/apt/sources.list.d/jenkins.list > /dev/null - -sudo apt-get update -y -sudo apt-get install jenkins -y -``` - -- After installing Jenkins, change the default port of jenkins from 8080 to 8081. Because our bankapp application will be running on 8080. - - Open /usr/lib/systemd/system/jenkins.service file and change JENKINS_PORT environment variable -![image](https://github.com/user-attachments/assets/6320ae49-82d4-4ae3-9811-bd6f06778483) - - Reload daemon - ```bash - sudo systemctl daemon-reload - ``` - - Restart Jenkins - ```bash - sudo systemctl restart jenkins - ``` +- GitHub Actions Setup (Replaces Jenkins) + - No server installation required - GitHub Actions runs in the cloud + - Configure repository secrets as documented in `.github/SECRETS.md` + - Workflows automatically trigger on push to DevOps branch + - Manual triggers available via workflow dispatch + +- Legacy Jenkins Installation (For Reference) + - Original Jenkins setup preserved in `legacy/jenkins/` directory + - Jenkins configuration replaced by GitHub Actions workflows # - Install docker diff --git a/cicd.md b/cicd.md index 140e1696..4b99fca3 100644 --- a/cicd.md +++ b/cicd.md @@ -1,108 +1,79 @@ -#### CICD Workflow -- Cloning the Project code from GitHub. -- Build docker image and push it to docker hub. -- Pull image from docker hub and deploy application using docker compose . +#### CICD Workflow (GitHub Actions) +- Cloning the Project code from GitHub using actions/checkout@v4 +- Security scanning with Trivy and OWASP dependency check +- Code quality analysis with SonarQube +- Build docker image and push it to docker hub +- GitOps deployment by updating Kubernetes manifests +- Email notifications for deployment status ![Login diagram](images/flow.png) -#### Creating CICD pipeline - 1. #### Install Jenkins and access on port 8080 - ```bash - http://:8080 - # Development environment only - http://:8080 +## Migration from Jenkins to GitHub Actions + +This repository has been migrated from Jenkins-based CI/CD to GitHub Actions workflows. The legacy Jenkins configuration files are preserved in the `legacy/jenkins/` directory for reference. + +### Jenkins to GitHub Actions Mapping + +| Jenkins Function | GitHub Actions Equivalent | +|------------------|---------------------------| +| `code_checkout()` | `actions/checkout@v4` | +| `trivy_scan()` | Trivy CLI installation and execution | +| `owasp_dependency()` | `dependency-check/Dependency-Check_Action@main` | +| `sonarqube_analysis()` | SonarQube Scanner CLI | +| `sonarqube_code_quality()` | `sonarqube-quality-gate-action@master` | +| `docker_build()` | Docker CLI commands | +| `docker_push()` | `docker/login-action@v3` + Docker CLI | + +#### Creating CICD pipeline (GitHub Actions) + + 1. #### Configure GitHub Actions (Replaces Jenkins) + - No server installation required + - Configure repository secrets in GitHub repository settings + - Access workflows at: `https://github.com/COG-GTM/Springboot-BankApp/actions` + - Workflows automatically trigger on code changes + +2. #### GitHub Actions Configuration. + - **Runners**: GitHub-hosted runners (ubuntu-latest) provide isolated execution environment + - **Security**: Built-in Docker support with secure credential management + - **Secrets Management**: + - Configure repository secrets in Settings > Secrets and variables > Actions + - Required secrets documented in `.github/SECRETS.md` + - Includes Docker Hub, SonarQube, and email notification credentials + - **Workflow Triggers**: + - Automatic triggers on push/PR to DevOps/main branches + - Manual triggers via workflow dispatch + - Repository dispatch for CI/CD pipeline coordination + +3. #### GitHub Actions Workflows and Triggers + + - **CI Workflow** (`.github/workflows/ci.yml`): + - Triggers on push/PR to DevOps/main branches + - Manual trigger via workflow dispatch with custom Docker tags + - Includes all security scanning, code quality, and Docker operations - # Production environment (recommended) - # Access through reverse proxy with HTTPS - https:///jenkins - ``` - Login and install Suggested Plugins. - -2. #### Jenkins Configuration. - - SetUp Agent - - Agents are used for distribute the builds in parallel execution - ![Agent](images/agent.png) - - - Install Docker and docker-compose:V2 on worker node and add the user who is executing the Jenkins job into the docker group. because we are going to deploy application in worker node itself. - - **Note** Security Considerations for Docker Setup. When configuring Docker for Jenkins: - - - Avoid adding the Jenkins user to the Docker group, as it grants root-level access. - - Use Rootless Docker to run Docker daemons and containers without root privileges. [Official Guide](https://docs.docker.com/engine/security/rootless/). - - Configure sudo for Docker commands: - - Grant specific permissions in the sudoers file. - - Use sudo in your pipeline scripts to execute Docker commands. - - Implement access control mechanisms using Docker authorization plugins or socket proxies. - + - **CD Workflow** (`.github/workflows/cd.yml`): + - Triggers via repository dispatch from CI workflow + - Manual trigger for specific Docker tag deployments + - Updates Kubernetes manifests and sends notifications - - - Configure Shared Library - - Configure the task effectively in centralized manner. - - Configure shared library for your Jenkins Server Navigate through Dashboard > Manage Jenkins > System, and add Global Trusted Pipeline Libraries. (Modern SCM) - - ![Shared-library](images/shared_library.png) - - - - Configure Crendentials. - - Credentials that are requied during job execution. - - e.g. DockerHub credentials for push and pull images. + - **Automatic Triggers**: + - No webhook configuration needed - GitHub Actions triggers automatically + - Built-in integration with GitHub repository events + - Secure and immediate execution without polling delays - ![Shared-library](images/credentials.png) - -3. #### Create a Pipeline, Execute Job and Configure Webhook - - - Configure Pipeline. - - Configure job to get pipeline from SCM. - ![pipeline](images/pipeline.png) - - Build Job and Check - - Build the Job - - Configure WebHook and poll SCM. - - Webhook Configuration - - 1. **Install GitHub Plugin** - - Go to `Manage Jenkins > Manage Plugins > Available`. - - Search for **GitHub Integration Plugin**, install, and restart Jenkins if needed. - - 2. **Configure Jenkins Job** - - In job configuration, enable **GitHub hook trigger for GITScm polling** under **Build Triggers**. - - 3. **Set Up Webhook in GitHub** - - Go to `Repository > Settings > Webhooks > Add webhook`. - - Configure: - - **Payload URL**: `http://:8080/github-webhook/` - - **Content type**: `application/json` - - **Events**: Select **push** or others as needed. - - (Optional) Add a secret token for security. - - 4. **Test Webhook** - - Push changes to the repo and verify the job is triggered. - - Check webhook status under **Recent Deliveries** in GitHub. - - - SCM Polling Configuration - - 1. **Enable SCM Polling** - - In job configuration, select **Poll SCM** under **Build Triggers**. - - Add a cron expression in **Schedule**: - - Every 5 minutes: `H/5 * * * *` - - Every 15 minutes: `H/15 * * * *` - - 2. **Test Polling** - - Push changes to the repo and wait for the next polling interval. - - Verify in **Polling Log** under the Jenkins job dashboard. - - - - Key Notes - - - **Webhooks vs Polling**: - - Webhooks are immediate and resource-efficient. - - Polling introduces delays and higher resource usage. - - - **Security**: - - Use SSL/TLS for GitHub-Jenkins communication. - - Ensure Jenkins is accessible via the firewall. - - - **Jenkins Pipeline**: - - Ensure `Jenkinsfile` is correctly configured to check out the repo and branch. + - **Manual Execution**: + ```bash + # Trigger CI workflow manually + gh workflow run ci.yml --ref DevOps -f docker_tag=manual-v1.0 + + # Trigger CD workflow manually + gh workflow run cd.yml --ref DevOps -f docker_tag=manual-v1.0 + ``` + + - **Monitoring**: + - View workflow runs at: `https://github.com/COG-GTM/Springboot-BankApp/actions` + - Real-time logs and status updates + - Email notifications for deployment status @@ -115,4 +86,4 @@ -#### Nginx and HTTPS [guide](nginx.md) \ No newline at end of file +#### Nginx and HTTPS [guide](nginx.md) diff --git a/Jenkinsfile b/legacy/jenkins/Jenkinsfile similarity index 100% rename from Jenkinsfile rename to legacy/jenkins/Jenkinsfile diff --git a/GitOps/Jenkinsfile b/legacy/jenkins/Jenkinsfile-CD similarity index 100% rename from GitOps/Jenkinsfile rename to legacy/jenkins/Jenkinsfile-CD diff --git a/legacy/jenkins/README.md b/legacy/jenkins/README.md new file mode 100644 index 00000000..864f7d5b --- /dev/null +++ b/legacy/jenkins/README.md @@ -0,0 +1,39 @@ +# Legacy Jenkins Configuration + +This directory contains the original Jenkins pipeline configuration files that were used before migrating to GitHub Actions. + +## Files + +- `Jenkinsfile`: Original CI pipeline with 8 stages including security scanning, code quality, and Docker operations +- `Jenkinsfile-CD`: Original CD pipeline for GitOps deployment and Kubernetes manifest updates +- `vars/`: Shared library functions used by the Jenkins pipelines + +## Migration Notes + +These files have been preserved for reference and historical purposes. The equivalent functionality is now implemented in GitHub Actions workflows: + +- `.github/workflows/ci.yml`: Replaces the Jenkins CI pipeline +- `.github/workflows/cd.yml`: Replaces the Jenkins CD pipeline + +## Shared Library Functions + +The Jenkins shared library functions have been replaced with equivalent GitHub Actions steps: + +| Jenkins Function | GitHub Actions Equivalent | +|------------------|---------------------------| +| `code_checkout()` | `actions/checkout@v4` | +| `trivy_scan()` | Trivy CLI installation and execution | +| `owasp_dependency()` | `dependency-check/Dependency-Check_Action@main` | +| `sonarqube_analysis()` | SonarQube Scanner CLI | +| `sonarqube_code_quality()` | `sonarqube-quality-gate-action@master` | +| `docker_build()` | Docker CLI commands | +| `docker_push()` | `docker/login-action@v3` + Docker CLI | + +## Credentials Migration + +Jenkins credentials have been migrated to GitHub Actions secrets: + +- Jenkins `docker` credential → `DOCKERHUB_USERNAME` + `DOCKERHUB_TOKEN` +- Jenkins `Github-cred` credential → Built-in `GITHUB_TOKEN` +- Jenkins SonarQube configuration → `SONAR_TOKEN` + `SONAR_HOST_URL` +- Jenkins email configuration → Email secrets in GitHub Actions diff --git a/vars/README.md b/legacy/jenkins/vars/README.md similarity index 100% rename from vars/README.md rename to legacy/jenkins/vars/README.md diff --git a/vars/buildImage.groovy b/legacy/jenkins/vars/buildImage.groovy similarity index 100% rename from vars/buildImage.groovy rename to legacy/jenkins/vars/buildImage.groovy diff --git a/vars/codeCheckout.groovy b/legacy/jenkins/vars/codeCheckout.groovy similarity index 100% rename from vars/codeCheckout.groovy rename to legacy/jenkins/vars/codeCheckout.groovy diff --git a/vars/code_checkout.groovy b/legacy/jenkins/vars/code_checkout.groovy similarity index 100% rename from vars/code_checkout.groovy rename to legacy/jenkins/vars/code_checkout.groovy diff --git a/vars/deploy.groovy b/legacy/jenkins/vars/deploy.groovy similarity index 100% rename from vars/deploy.groovy rename to legacy/jenkins/vars/deploy.groovy diff --git a/vars/docker_build.groovy b/legacy/jenkins/vars/docker_build.groovy similarity index 100% rename from vars/docker_build.groovy rename to legacy/jenkins/vars/docker_build.groovy diff --git a/vars/docker_cleanup.groovy b/legacy/jenkins/vars/docker_cleanup.groovy similarity index 100% rename from vars/docker_cleanup.groovy rename to legacy/jenkins/vars/docker_cleanup.groovy diff --git a/vars/docker_compose.groovy b/legacy/jenkins/vars/docker_compose.groovy similarity index 100% rename from vars/docker_compose.groovy rename to legacy/jenkins/vars/docker_compose.groovy diff --git a/vars/docker_push.groovy b/legacy/jenkins/vars/docker_push.groovy similarity index 100% rename from vars/docker_push.groovy rename to legacy/jenkins/vars/docker_push.groovy diff --git a/vars/greet.groovy b/legacy/jenkins/vars/greet.groovy similarity index 100% rename from vars/greet.groovy rename to legacy/jenkins/vars/greet.groovy diff --git a/vars/owasp_dependency.groovy b/legacy/jenkins/vars/owasp_dependency.groovy similarity index 100% rename from vars/owasp_dependency.groovy rename to legacy/jenkins/vars/owasp_dependency.groovy diff --git a/vars/pushImage.groovy b/legacy/jenkins/vars/pushImage.groovy similarity index 100% rename from vars/pushImage.groovy rename to legacy/jenkins/vars/pushImage.groovy diff --git a/vars/sonarqube_analysis.groovy b/legacy/jenkins/vars/sonarqube_analysis.groovy similarity index 100% rename from vars/sonarqube_analysis.groovy rename to legacy/jenkins/vars/sonarqube_analysis.groovy diff --git a/vars/sonarqube_code_quality.groovy b/legacy/jenkins/vars/sonarqube_code_quality.groovy similarity index 100% rename from vars/sonarqube_code_quality.groovy rename to legacy/jenkins/vars/sonarqube_code_quality.groovy diff --git a/vars/trivy_scan.groovy b/legacy/jenkins/vars/trivy_scan.groovy similarity index 100% rename from vars/trivy_scan.groovy rename to legacy/jenkins/vars/trivy_scan.groovy