diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..2aabf9d1 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,94 @@ +name: Hprofile Actions +#on: workflow_dispatch # [push, workflow_dispatch] +on: + push: + branches: + - master + workflow_dispatch: +env: + AWS_REGION: us-east-1 +jobs: + Testing: + runs-on: ubuntu-latest + steps: + - name: code checkout + uses: actions/checkout@v4 + + - name: Maven test + run: mvn test + + - name: Checkstyle + run: mvn checkstyle:checkstyle + + - name: Set Java 11 + uses: actions/setup-java@v2 + with: + distribution: 'adopt' + java-version: '11' + + - name: Setup SonarQube + uses: warchant/setup-sonar-scanner@v7 + + # Run sonar-scanner + - name: SonarQube Scan + run: sonar-scanner + -Dsonar.host.url=${{ secrets.SONAR_URL }} + -Dsonar.login=${{ secrets.SONAR_TOKEN }} + -Dsonar.organization=${{ secrets.SONAR_ORGANIZATION }} + -Dsonar.projectKey=${{ secrets.SONAR_PROJECT_KEY }} + -Dsonar.sources=src/ + -Dsonar.junit.reportsPath=target/surefire-report/ + -Dsonar.jacoco.reportsPath=target/jacoco.exec + -Dsonar.java.checkstyle.reportsPath=target/checkstyle-result.xml + -Dsonar.java.binaries=target/test-classes/com/visualpathit/account + + # Check the Quality Gate status. + - name: SonarQube Quality Gate check + id: sonarqube-quality-gate-check + uses: sonarsource/sonarqube-quality-gate-action@master + # Force to fail step after specific time. + timeout-minutes: 5 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_URL }} #OPTIONAL + + BUILD_AND_PUBLISH: + needs: Testing + runs-on: ubuntu-latest + steps: + - name: code checkout + uses: actions/checkout@v4 + +# - name: Update application.properties file +# run: | +# sed -i "s/^jdbc.username.*$/jdbc.username\=${{ secrets.RDS_USER }}/" src/main/resources/application.properties +# sed -i "s/^jdbc.password.*$/jdbc.password\=${{ secrets.RDS_PASS }}/" src/main/resources/application.properties +# sed -i "s/db01/${{ secrets.RDS_ENDPOINT }}/" src/main/resources/application.properties + + - name: upload image to ECR + uses: appleboy/docker-ecr-action@master + with: + access_key: ${{ secrets.AWS_ACCESS_KEY_ID }} + secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + registry: ${{ secrets.REGISTRY }} + repo: docker + region: ${{ env.AWS_REGION }} + tags: ${{ github.run_number }} #latest,${{ github.run_number }} + daemon_off: false + dockerfile: ./Dockerfile + context: ./ + + - name: Update Image tag + run: | + sed -i "s|image:.*|image: 637423293208.dkr.ecr.us-east-1.amazonaws.com/docker:${{ github.run_number }} |" ./java.yaml + + - name: Commit changes + run: | + git config --global user.name ${{ secrets.USER_NAME }} + git config --global user.email ${{ secrets.USER_MAIL }} + git add java.yaml + git commit -m "Update image to ${{ github.run_number }}" + git push + + + diff --git a/EKS/01-Nginx-App1-Deployment-and-NodePortService.yml b/EKS/01-Nginx-App1-Deployment-and-NodePortService.yml new file mode 100644 index 00000000..5a9b6d94 --- /dev/null +++ b/EKS/01-Nginx-App1-Deployment-and-NodePortService.yml @@ -0,0 +1,40 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: app1-nginx-deployment + labels: + app: app1-nginx +spec: + replicas: 1 + selector: + matchLabels: + app: app1-nginx + template: + metadata: + labels: + app: app1-nginx + spec: + containers: + - name: app1-nginx + image: stacksimplify/kube-nginxapp1:1.0.0 + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + name: app1-nginx-nodeport-service + labels: + app: app1-nginx + annotations: +#Important Note: Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer +# alb.ingress.kubernetes.io/healthcheck-path: /app1/index.html +spec: + type: NodePort + selector: + app: app1-nginx + ports: + - port: 80 + targetPort: 80 + + \ No newline at end of file diff --git a/EKS/01-ingressclass-resource.yaml b/EKS/01-ingressclass-resource.yaml new file mode 100644 index 00000000..8196bef5 --- /dev/null +++ b/EKS/01-ingressclass-resource.yaml @@ -0,0 +1,13 @@ +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + name: my-aws-ingress-class + annotations: + ingressclass.kubernetes.io/is-default-class: "true" +spec: + controller: ingress.k8s.aws/alb + +## Additional Note +# 1. You can mark a particular IngressClass as the default for your cluster. +# 2. Setting the ingressclass.kubernetes.io/is-default-class annotation to true on an IngressClass resource will ensure that new Ingresses without an spec.ingressClassName field specified will be assigned this default IngressClass. +# 3. Reference: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.3/guide/ingress/ingress_class/ \ No newline at end of file diff --git a/EKS/02-ALB-Ingress-Basic.yml b/EKS/02-ALB-Ingress-Basic.yml new file mode 100644 index 00000000..d2759d82 --- /dev/null +++ b/EKS/02-ALB-Ingress-Basic.yml @@ -0,0 +1,38 @@ +# Annotations Reference: https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/ingress/annotations/ +# Annotations Reference: https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/ingress/annotations/ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress-nginxapp1 + labels: + app: app1-nginx + annotations: + # Load Balancer Name + alb.ingress.kubernetes.io/load-balancer-name: app1ingressrules + #kubernetes.io/ingress.class: "alb" (OLD INGRESS CLASS NOTATION - STILL WORKS BUT RECOMMENDED TO USE IngressClass Resource) + # Ingress Core Settings + alb.ingress.kubernetes.io/scheme: internet-facing + # Health Check Settings + alb.ingress.kubernetes.io/healthcheck-protocol: HTTP + alb.ingress.kubernetes.io/healthcheck-port: traffic-port + alb.ingress.kubernetes.io/healthcheck-path: /app1/index.html + alb.ingress.kubernetes.io/healthcheck-interval-seconds: '15' + alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5' + alb.ingress.kubernetes.io/success-codes: '200' + alb.ingress.kubernetes.io/healthy-threshold-count: '2' + alb.ingress.kubernetes.io/unhealthy-threshold-count: '2' +spec: + ingressClassName: my-aws-ingress-class # Ingress Class + rules: + - http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: app1-nginx-nodeport-service + port: + number: 80 + +# 1. If "spec.ingressClassName: my-aws-ingress-class" not specified, will reference default ingress class on this kubernetes cluster +# 2. Default Ingress class is nothing but for which ingress class we have the annotation `ingressclass.kubernetes.io/is-default-class: "true"` diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index 7fecd3c2..00000000 --- a/Jenkinsfile +++ /dev/null @@ -1,122 +0,0 @@ -pipeline { - - agent any -/* - tools { - maven "maven3" - - } -*/ - environment { - NEXUS_VERSION = "nexus3" - NEXUS_PROTOCOL = "http" - NEXUS_URL = "172.31.40.209:8081" - NEXUS_REPOSITORY = "vprofile-release" - NEXUS_REPO_ID = "vprofile-release" - NEXUS_CREDENTIAL_ID = "nexuslogin" - ARTVERSION = "${env.BUILD_ID}" - } - - stages{ - - stage('BUILD'){ - steps { - sh 'mvn clean install -DskipTests' - } - post { - success { - echo 'Now Archiving...' - archiveArtifacts artifacts: '**/target/*.war' - } - } - } - - stage('UNIT TEST'){ - steps { - sh 'mvn test' - } - } - - stage('INTEGRATION TEST'){ - steps { - sh 'mvn verify -DskipUnitTests' - } - } - - stage ('CODE ANALYSIS WITH CHECKSTYLE'){ - steps { - sh 'mvn checkstyle:checkstyle' - } - post { - success { - echo 'Generated Analysis Result' - } - } - } - - stage('CODE ANALYSIS with SONARQUBE') { - - environment { - scannerHome = tool 'sonarscanner4' - } - - steps { - withSonarQubeEnv('sonar-pro') { - sh '''${scannerHome}/bin/sonar-scanner -Dsonar.projectKey=vprofile \ - -Dsonar.projectName=vprofile-repo \ - -Dsonar.projectVersion=1.0 \ - -Dsonar.sources=src/ \ - -Dsonar.java.binaries=target/test-classes/com/visualpathit/account/controllerTest/ \ - -Dsonar.junit.reportsPath=target/surefire-reports/ \ - -Dsonar.jacoco.reportsPath=target/jacoco.exec \ - -Dsonar.java.checkstyle.reportPaths=target/checkstyle-result.xml''' - } - - timeout(time: 10, unit: 'MINUTES') { - waitForQualityGate abortPipeline: true - } - } - } - - stage("Publish to Nexus Repository Manager") { - steps { - script { - pom = readMavenPom file: "pom.xml"; - filesByGlob = findFiles(glob: "target/*.${pom.packaging}"); - echo "${filesByGlob[0].name} ${filesByGlob[0].path} ${filesByGlob[0].directory} ${filesByGlob[0].length} ${filesByGlob[0].lastModified}" - artifactPath = filesByGlob[0].path; - artifactExists = fileExists artifactPath; - if(artifactExists) { - echo "*** File: ${artifactPath}, group: ${pom.groupId}, packaging: ${pom.packaging}, version ${pom.version} ARTVERSION"; - nexusArtifactUploader( - nexusVersion: NEXUS_VERSION, - protocol: NEXUS_PROTOCOL, - nexusUrl: NEXUS_URL, - groupId: pom.groupId, - version: ARTVERSION, - repository: NEXUS_REPOSITORY, - credentialsId: NEXUS_CREDENTIAL_ID, - artifacts: [ - [artifactId: pom.artifactId, - classifier: '', - file: artifactPath, - type: pom.packaging], - [artifactId: pom.artifactId, - classifier: '', - file: "pom.xml", - type: "pom"] - ] - ); - } - else { - error "*** File: ${artifactPath}, could not be found"; - } - } - } - } - - - } - - -} diff --git a/README.md b/README.md index dc93c30f..1dfdfc33 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Prerequisites -##### +########### - JDK 11 - Maven 3 - MySQL 8 diff --git a/bash.sh b/bash.sh new file mode 100644 index 00000000..6f2cd805 --- /dev/null +++ b/bash.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +sudo eksctl create iamserviceaccount \ + --cluster=demo-cluster \ + --namespace=kube-system \ + --name=aws-load-balancer-controller \ + --region=us-east-1 \ + --attach-role-arn arn:aws:iam::637423293208:role/aws-service-controller-eks-role \ + --approve + +# eksctl get iamserviceaccount --cluster demo-cluster + +helm repo add eks https://aws.github.io/eks-charts + +helm repo update eks + +#helm repo remove eks + +helm install aws-load-balancer-controller eks/aws-load-balancer-controller \ + -n kube-system \ + --set clusterName=demo-cluster \ + --set serviceAccount.create=false \ + --set serviceAccount.name=aws-load-balancer-controller \ + --set image.repository=602401143452.dkr.ecr.us-east-1.amazonaws.com/amazon/aws-load-balancer-controller \ + --set image.tag=v2.7.1 \ + --set region=us-east-1 \ + --set vpcId=vpc-07d3c084b26a40ddd + +#helm unstall aws-load-balancer-controller + +# Deploy EBS CSI Driver +kubectl apply -k "github.com/kubernetes-sigs/aws-ebs-csi-driver/deploy/kubernetes/overlays/stable/?ref=master" + +#kubectl delete -k "github.com/kubernetes-sigs/aws-ebs-csi-driver/deploy/kubernetes/overlays/stable/?ref=master" + +# Verify ebs-csi pods running +kubectl get pods -n kube-system \ No newline at end of file diff --git a/java.yaml b/java.yaml new file mode 100644 index 00000000..d1bb73cb --- /dev/null +++ b/java.yaml @@ -0,0 +1,32 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: java-deployment +spec: + selector: + matchLabels: + app.kubernetes.io/name: java-app + replicas: 1 # tells deployment to run 2 pods matching the template + template: + metadata: + labels: + app.kubernetes.io/name: java-app + spec: + containers: + - name: java + image: 637423293208.dkr.ecr.us-east-1.amazonaws.com/docker:36 + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + name: java-service +spec: + ports: + - port: 8080 + targetPort: 80 + type: ClusterIP + selector: + app.kubernetes.io/name: java-app \ No newline at end of file diff --git a/pipeline-script.sh b/pipeline-script.sh new file mode 100644 index 00000000..1f9c1f00 --- /dev/null +++ b/pipeline-script.sh @@ -0,0 +1,120 @@ +name: Hprofile Actions +on: workflow_dispatch # [push, workflow_dispatch] +env: + AWS_REGION: us-east-1 +jobs: + Testing: + runs-on: ubuntu-latest + steps: + - name: code checkout + uses: actions/checkout@v4 + + - name: Maven test + run: mvn test + + - name: Checkstyle + run: mvn checkstyle:checkstyle + + - name: Set Java 11 + uses: actions/setup-java@v2 + with: + distribution: 'adopt' + java-version: '11' + + - name: Setup SonarQube + uses: warchant/setup-sonar-scanner@v7 + + # Run sonar-scanner + - name: SonarQube Scan + run: sonar-scanner + -Dsonar.host.url=${{ secrets.SONAR_URL }} + -Dsonar.login=${{ secrets.SONAR_TOKEN }} + -Dsonar.organization=${{ secrets.SONAR_ORGANIZATION }} + -Dsonar.projectKey=${{ secrets.SONAR_PROJECT_KEY }} + -Dsonar.sources=src/ + -Dsonar.junit.reportsPath=target/surefire-report/ + -Dsonar.jacoco.reportsPath=target/jacoco.exec + -Dsonar.java.checkstyle.reportsPath=target/checkstyle-result.xml + -Dsonar.java.binaries=target/test-classes/com/visualpathit/account + + # Check the Quality Gate status. + - name: SonarQube Quality Gate check + id: sonarqube-quality-gate-check + uses: sonarsource/sonarqube-quality-gate-action@master + # Force to fail step after specific time. + timeout-minutes: 5 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_URL }} #OPTIONAL + + BUILD_AND_PUBLISH: + needs: Testing + runs-on: ubuntu-latest + steps: + - name: code checkout + uses: actions/checkout@v4 + +# - name: Update application.properties file +# run: | +# sed -i "s/^jdbc.username.*$/jdbc.username\=${{ secrets.RDS_USER }}/" src/main/resources/application.properties +# sed -i "s/^jdbc.password.*$/jdbc.password\=${{ secrets.RDS_PASS }}/" src/main/resources/application.properties +# sed -i "s/db01/${{ secrets.RDS_ENDPOINT }}/" src/main/resources/application.properties + + - name: upload image to ECR + uses: appleboy/docker-ecr-action@master + with: + access_key: ${{ secrets.AWS_ACCESS_KEY_ID }} + secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + registry: ${{ secrets.REGISTRY }} + repo: docker + region: ${{ env.AWS_REGION }} + tags: ${{ github.run_number }} #latest,${{ github.run_number }} + daemon_off: false + dockerfile: ./Dockerfile + context: ./ + + - name: Update Image tag in deployment file + run: | + sed -i "s|image:.*|image: 637423293208.dkr.ecr.us-east-1.amazonaws.com/docker:${{ github.run_number }} |" ./java.yaml + + - name: Commit changes + run: | + git config --global user.name ${{ secrets.USER_NAME }} + git config --global user.email ${{ secrets.USER_MAIL }} + git add java.yaml + git commit -m "Update image to ${{ github.run_number }}" + git push + + DEPLOY: + # needs: BUILD_AND_PUBLISH + runs-on: ubuntu-latest + steps: + - name: code checkout + uses: actions/checkout@v4 + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 + + - name: update kube config + run: aws eks update-kubeconfig --region us-east-1 --name demo-cluster + + - name: Install eksctl + run: | + curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp + sudo mv /tmp/eksctl /usr/local/bin + eksctl version + + - name: Run bash.sh + run: | + chmod +x ./bash.sh + ./bash.sh + + - name: Deploy to EKS cluster + run: | + + kubectl apply -f EKS/ +