Automating Tetris Deployments: DevSecOps with ArgoCD, Terraform, and Jenkins for Two Game Versions

In these Project , We Are deploying the two Tetris game versions with DevSecOps Plugins using the Jenkins CI/CD and ArgoCD . Here, All whole these infrastructure created on the Using Terraform.

What is the argo CD ?

Argo CD is an open-source declarative continuous delivery (CD) tool for Kubernetes applications. It is designed to automate the deployment and continuous delivery of applications running on Kubernetes clusters. Argo CD helps manage the configuration of applications, ensuring that they are deployed and maintained consistently across different environments.

Prerequisites:

  1. AWS Account: To get started, you'll need an active AWS account. Ensure that you have access and permission to create and manage AWS resources.

  2. AWS CLI: Install the AWS Command Line Interface (CLI) on your local machine and configure it with your AWS credentials. This is essential for managing your AWS resources.

  3. IAM User and Key Pair: Create an IAM (Identity and Access Management) user with the necessary permissions to provision resources on AWS. Additionally, generate an IAM Access Key and Secret Access Key for programmatic access. Ensure that you securely manage these credentials.

  4. S3 Bucket: Set up an S3 bucket to store your Terraform state files. This bucket is crucial for maintaining the state of your infrastructure and enabling collaboration.

  5. Terraform: Install Terraform on your local machine. Terraform is used for provisioning infrastructure as code and managing AWS resources. Make sure to configure Terraform to work with your AWS credentials and your S3 bucket for state storage.

Step1: How to install and setup Terraform on Windows

Download Terraform:

Visit the official Terraform website: terraform.io/downloads.html

Extract the ZIP Archive:

Once the download is complete, extract the contents of the ZIP archive to a directory on your computer. You can use a tool like 7-Zip or the built-in Windows extraction tool. Ensure that you extract it to a directory that's part of your system's PATH.

Remember that I created a Terraform Directory in C drive

Extracted to C drive -> Copy the path

Add Terraform to Your System's PATH:

To make Terraform easily accessible from the command prompt, add the directory where Terraform is extracted to your system's PATH environment variable. Follow these steps:

Search for "Environment Variables" in your Windows search bar and click "Edit the system environment variables."

In the "System Properties" window, click the "Environment Variables" button.

Under "User variables for Admin," find the "Path" variable and click "Edit."

Click on New paste the copied path and click on OK

Under "System variables," find the "Path" variable and click "Edit."

Click "New" and add the path to the directory where you extracted Terraform (e.g., C:\path\to\terraform)

Click "OK" to close the Environment Variables windows.

Click "OK" again to close the System Properties window.

Verify the Installation:

Open a new Command Prompt or PowerShell window.

Type terraform --version and press Enter. This command should display the Terraform version, confirming that Terraform is installed and in your PATH.

Step2: Download the AWS CLI Installer:

Visit the AWS CLI Downloads page: aws.amazon.com/cli

Under "Install the AWS CLI," click on the "64-bit" link to download the AWS CLI installer for Windows.

Run the Installer: - > Click on install -> Click Finish Aws cli is installed

Verify the Installation:

Open a Command Prompt or PowerShell window.

Type aws --version and press Enter. This command should display the AWS CLI version, confirming that the installation was successful.

Step3: create an IAM user

Navigate to the AWS console

Click the "Search" field. -> Search for IAM -> Click "Users -> Click "Add users" -> Click the "User name" field. -> Type "Terraform" or as you wish about the name -> Click Next -> Click "Attach policies directly" -> Click "Attach policies directly" -> Click "Next"

goto security Credentials -> Create access & secreate acccess key -> Click this button with the CLI -> Agree to terms -> Click "Create access key" -> Download .csv file

Step4: Aws Configure

Go to vs code or Cmd your wish

Step5: Terraform files and Provision

CHANGE YOUR S3 BUCKET NAME IN THE BACKEND.TF

Clone the repository to your local file explorer

https://github.com/Bhushan0151/Tetris-V1.git
cd Tetris-V1
cd Jenkins-terraform
ls #to see files

Now you can see the terraform files to provision the AWS Ec2 with Jenkins installed,sonarqube container and Trivy, Aws cli,Kubectl and terraform

install.sh

Shell script

```shellscript

#!/bin/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/jenkins.io-2023.key
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update -y
sudo apt-get install jenkins -y
sudo systemctl start jenkins
sudo systemctl status jenkins
sudo systemctl enable jenkins

#install docker
sudo apt-get update
sudo apt-get install docker.io -y
sudo usermod -aG docker ubuntu  
newgrp docker
sudo chmod 777 /var/run/docker.sock
docker run -d --name sonar -p 9000:9000 sonarqube:lts-community

#install trivy
sudo apt-get install wget apt-transport-https gnupg lsb-release -y
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] 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 -y


#install terraform
sudo apt install wget -y
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform

#install Kubectl on Jenkins
sudo apt update
sudo apt install curl -y
curl -LO https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
kubectl version --client

#install Aws cli 
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
sudo apt-get install unzip -y
unzip awscliv2.zip
sudo ./aws/install


```

Now inside the Jenkins-terraform directory

Open the terminal and provide the below commands

terraform init
terraform validate
terraform plan
terraform apply --auto-approve

Apply completed you can see Ec2 is created in the Aws console

Now copy the public IP address of ec2 and paste it into the browser

<Ec2-ip:8080> #you will Jenkins login page
    sudo cat /var/lib/jenkins/secrets/initialAdminPassword

Jenkins Console -

Now Copy the public IP again and paste it into a new tab in the browser with 9000

<ec2-ip:9000>  #runs sonar container
username admin
password admin

Now go to Putty and see whether it's installed Trivy, Terraform, Aws cli, Kubectl or not.

trivy --version 
aws --version
terraform --version
kubectl version

That is done now go to Jenkins and add a terraform plugin to provision the AWS EKS using the Pipeline Job.

Go to Jenkins dashboard --> Manage Jenkins --> Plugins

Available Plugins, Search for Terraform and install it.

Go to Putty and use the below command

let's find the path to our Terraform (we will use it in the tools section of Terraform)

which terraform

Now come back to Manage Jenkins --> Tools

Add the terraform in Tools

Apply and save.

CHANGE YOUR S3 BUCKET NAME IN THE BACKEND.TF

Step 6 : Now create a new job for the Eks provision

pipeline{
    agent any
    stages {
        stage('Checkout from Git'){
            steps{
                git branch: 'main', url: 'https://github.com/Bhushan0151/Tetris-V1.git'
            }
        }
        stage('Terraform version'){
             steps{
                 sh 'terraform --version'
             }
        }
        stage('Terraform init'){
             steps{
                 dir('Eks-terraform') {
                      sh 'terraform init'
                   }      
             }
        }
        stage('Terraform validate'){
             steps{
                 dir('Eks-terraform') {
                      sh 'terraform validate'
                   }      
             }
        }
        stage('Terraform plan'){
             steps{
                 dir('Eks-terraform') {
                      sh 'terraform plan'
                   }      
             }
        }
        stage('Terraform apply/destroy'){
             steps{
                 dir('Eks-terraform') {
                      sh 'terraform ${action} --auto-approve'
                   }      
             }
        }
    }
}

Check in Your Aws console whether it created EKS or not.

Ec2 instance is created for the Node group

Now let's build Tetris version 1

We need some plugins to complete this process

Go to Jenkins dashboard

Manage Jenkins --> Plugins --> Available Plugins

Search for the Below Plugins

Eclipse Temurin installer

Sonarqube Scanner

NodeJs

Owasp Dependency-Check

Docker

Docker Commons

Docker Pipeline

Docker API

Docker-build-step

Configure in Global Tool Configuration

Goto Manage Jenkins → Tools → Install JDK(17) and NodeJs(16)→ Click on Apply and Save

For Sonarqube use the latest version

For Owasp use the 6.5.1 version

Use the latest version of Docker

Click apply and save.

Configure Sonar Server in Manage Jenkins

Grab the Public IP Address of your EC2 Instance, Sonarqube works on Port 9000, so <Public IP>:9000.

Goto your Sonarqube Server. Click on Administration → Security → Users → Click on Tokens and Update Token → Give it a name → and click on Generate Token -> click on update Token

Create a token with a name and generate

Now add Docker credentials to the Jenkins to log in and push the image

Manage Jenkins --> Credentials --> global --> add credential

Add DockerHub Username and Password under Global Credentials

Version 1.0

Task 1 : Now let's create a new job for our pipeline

pipeline{
    agent any
    tools{
        jdk 'jdk17'
        nodejs 'node16'
    }
    environment {
        SCANNER_HOME=tool 'sonar-scanner'
    }
    stages {
        stage('clean workspace'){
            steps{
                cleanWs()
            }
        }
        stage('Checkout from Git'){
            steps{
                git branch: 'main', url: 'https://github.com/Bhushan0151/Tetris-V1.git'
            }
        }
        stage("Sonarqube Analysis "){
            steps{
                withSonarQubeEnv('sonar-server') {
                    sh ''' $SCANNER_HOME/bin/sonar-scanner -Dsonar.projectName=TetrisVersion1.0 \
                    -Dsonar.projectKey=TetrisVersion1.0 '''
                }
            }
        }
        stage("quality gate"){
           steps {
                script {
                    waitForQualityGate abortPipeline: false, credentialsId: 'Sonar-token' 
                }
            } 
        }
        stage('Install Dependencies') {
            steps {
                sh "npm install"
            }
        }
        stage('OWASP FS SCAN') {
            steps {
                dependencyCheck additionalArguments: '--scan ./ --disableYarnAudit --disableNodeAudit', odcInstallation: 'DP-Check'
                dependencyCheckPublisher pattern: '**/dependency-check-report.xml'
            }
        }
        stage('TRIVY FS SCAN') {
            steps {
                sh "trivy fs . > trivyfs.txt"
            }
        }
        stage("Docker Build & Push"){
            steps{
                script{
                   withDockerRegistry(credentialsId: 'docker', toolName: 'docker'){   
                       sh "docker build -t tetrisv1 ."
                       sh "docker tag tetrisv1 bhushann11/tetrisv1:latest "
                       sh "docker push bhushann11/tetrisv1:latest "
                    }
                }
            }
        }
        stage("TRIVY"){
            steps{
                sh "trivy image bhushann11/tetrisv1:latest > trivyimage.txt" 
            }
        }
    }
}

Click on Apply and save.

Build now

Stage view

To see the report, you can go to Sonarqube Server and go to Projects.

When you log in to Dockerhub, you will see a new image is created

Task 2 : Let's create a GitHub Token. Go to GitHub

Click on Your Profile on the top right -> Now go down and search for Developer settings and click on it -> Now click on Personal Access tokens -> Click on Tokens (Classic) -> Click on Generate New token --> Generate new token (classic) -> Now it asks for access provide your GitHub password -> Now provide a name for the token -> Click on all check box -> Now click on Generate token -> Now copy the token

Now go to the Jenkins dashboard

Manage Jenkins --> credentials --> Global

Add credential

Let's add the Image Updater stage to the Pipeline

#add inside environment

 environment {
    GIT_REPO_NAME = "Tetris-manifest"
    GIT_USER_NAME = "Bhushan0151"      // change your  Github Username here
  }

# add these stages after trivy image scan 
        stage('Checkout Code') {
            steps {
                git branch: 'main', url: 'https://github.com/Bhushan0151/Tetris-manifest.git'
            }
        }
        stage('Update Deployment File') {
            steps {
                script {
                    withCredentials([string(credentialsId: 'github', variable: 'GITHUB_TOKEN')]) {
                       NEW_IMAGE_NAME = "bhushann11/tetrisv1:latest"   #update your image here
                       sh "sed -i 's|image: .*|image: $NEW_IMAGE_NAME|' deployment.yml"
                       sh 'git add deployment.yml'
                       sh "git commit -m 'Update deployment image to $NEW_IMAGE_NAME'"
                       sh "git push https://${GITHUB_TOKEN}@github.com/${GIT_USER_NAME}/${GIT_REPO_NAME} HEAD:main"
                    }
                }
            }
        }

All Whole Pipeline - till here

pipeline{
    agent any
    tools{
        jdk 'jdk17'
        nodejs 'node16'
    }
    environment {
        SCANNER_HOME=tool 'sonar-scanner'
        GIT_REPO_NAME = "Tetris-manifest"
        GIT_USER_NAME = "Bhushan0151"      // change your  Github Username here
    }
    stages {
        stage('clean workspace'){
            steps{
                cleanWs()
            }
        }
        stage('Checkout from Git'){
            steps{
                git branch: 'main', url: 'https://github.com/Bhushan0151/Tetris-V1.git'
            }
        }
        stage("Sonarqube Analysis "){
            steps{
                withSonarQubeEnv('sonar-server') {
                    sh ''' $SCANNER_HOME/bin/sonar-scanner -Dsonar.projectName=TetrisVersion1.0 \
                    -Dsonar.projectKey=TetrisVersion1.0 '''
                }
            }
        }
        stage("quality gate"){
           steps {
                script {
                    waitForQualityGate abortPipeline: false, credentialsId: 'Sonar-token' 
                }
            } 
        }
        stage('Install Dependencies') {
            steps {
                sh "npm install"
            }
        }
        stage('OWASP FS SCAN') {
            steps {
                dependencyCheck additionalArguments: '--scan ./ --disableYarnAudit --disableNodeAudit', odcInstallation: 'DP-Check'
                dependencyCheckPublisher pattern: '**/dependency-check-report.xml'
            }
        }
        stage('TRIVY FS SCAN') {
            steps {
                sh "trivy fs . > trivyfs.txt"
            }
        }
        stage("Docker Build & Push"){
            steps{
                script{
                   withDockerRegistry(credentialsId: 'docker', toolName: 'docker'){   
                       sh "docker build -t tetrisv1 ."
                       sh "docker tag tetrisv1 bhushann11/tetrisv1:latest "
                       sh "docker push bhushann11/tetrisv1:latest "
                    }
                }
            }
        }
        stage("TRIVY"){
            steps{
                sh "trivy image bhushann11/tetrisv1:latest > trivyimage.txt" 
            }
        }
        
        stage('Manifest Checkout Code') {
            steps {
                git branch: 'main', url: 'https://github.com/Bhushan0151/Tetris-manifest.git'
            }
        }
        stage('Update Deployment File') {
            steps {
                script {
                    withCredentials([string(credentialsId: 'github', variable: 'GITHUB_TOKEN')]) {
                       NEW_IMAGE_NAME = "bhushann11/tetrisv1:latest"   //update your image here
                       sh "sed -i 's|image: .*|image: $NEW_IMAGE_NAME|' deployment.yml"
                       sh 'git add deployment.yml'
                       sh "git commit -m 'Update deployment image to $NEW_IMAGE_NAME'"
                       sh "git push https://${GITHUB_TOKEN}@github.com/${GIT_USER_NAME}/${GIT_REPO_NAME} HEAD:main"
                    }
                }
            }
        }
    }
}

SonarQube -

Task 3 : Let's Update the kubeconfig

Go to Putty of your Jenkins instance SSH and enter the below command

aws eks update-kubeconfig --name <CLUSTER NAME> --region <CLUSTER REGION>
aws eks update-kubeconfig --name EKS_CLOUD --region us-east-2

Let's see the nodes

kubectl get nodes

Task 4 : ARGO CD SETUP

Let's install ArgoCD

ARGOCD INSTALLATION LINK

You will redirected to this page

All those components could be installed using a manifest provided by the Argo Project: use the below commands

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.4.7/manifests/install.yaml

COMMANDS ARGOCD

By default, argocd-server is not publicly exposed. For this project, we will use a Load Balancer to make it usable:

kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

One load balancer will created in the AWS

Wait about 2 minutes for the LoadBalancer creation

sudo apt install jq -y
export ARGOCD_SERVER=`kubectl get svc argocd-server -n argocd -o json | jq --raw-output '.status.loadBalancer.ingress[0].hostname'`

when you run this command, it will export the hostname of the ArgoCD server's load balancer and store it in the ARGOCD_SERVER environment variable, which you can then use in other commands or scripts to interact with the ArgoCD server. This can be useful when you need to access the ArgoCD web UI or interact with the server programmatically.

Task 5 : Login

The command you provided is used to extract the password for the initial admin user of ArgoCD, decode it from base64 encoding, and store it in an environment variable named ARGO_PWD.

export ARGO_PWD=`kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d`

If you want to see your password provide the below command

echo $ARGO_PWD

Now copy the load balancer IP/dns name and paste it into the browser

echo $ARGOCD_SERVER

Now you will see this page. if you get an error click on advanced and click on proceed.

Now you will see this page and log in to ArgoCD

Username is admin

For the password, you have to provide the below command and copy it

echo $ARGO_PWD

Er4iPybjOhKYnlvq

Click on Sign in and you will see this page.

Now click on the Setting gear icon in the left side panel

Click on Repositories

Now click on Connect Repo Using HTTPS

Add Github details, Type as git, Project as default and provide the GitHub URL of this manifest and click on connect

You will get Connection Status as Successful

Click on Manage Your application

You will see this page and click on New App

Now provide the following details as in the image

Click on Create.

You can see our app is created in Argo-cd

Click on tetris and it will create another load balancer in AWS

Now click on three dots beside tetris-service and click on the details

Now copy the hostname address

Paste it in a browser you will see this page

Output - Version 1.0

kubectl get all

Version 2.0

Let's Build version 2.0 Tetris game

Task 1: Add this pipeline to the Job

pipeline{
    agent any
    tools{
        jdk 'jdk17'
        nodejs 'node16'
    }
    environment {
        SCANNER_HOME=tool 'sonar-scanner'
        GIT_REPO_NAME = "Tetris-manifest"
        GIT_USER_NAME = "Bhushan0151"      // change your Github Username here
    }
    stages {
        stage('clean workspace'){
            steps{
                cleanWs()
            }
        }
        stage('V2 - Checkout from Git'){
            steps{
                git branch: 'main', url: 'https://github.com/Bhushan0151/Tetris-V2.git'
            }
        }
        stage("Sonarqube Analysis "){
            steps{
                withSonarQubeEnv('sonar-server') {
                    sh ''' $SCANNER_HOME/bin/sonar-scanner -Dsonar.projectName=TetrisVersion2.0 \
                    -Dsonar.projectKey=TetrisVersion2.0 '''
                }
            }
        }
        stage("quality gate"){
           steps {
                script {
                    waitForQualityGate abortPipeline: false, credentialsId: 'Sonar-token' 
                }
            } 
        }
        stage('Install Dependencies') {
            steps {
                sh "npm install"
            }
        }
        stage('OWASP FS SCAN') {
            steps {
                dependencyCheck additionalArguments: '--scan ./ --disableYarnAudit --disableNodeAudit', odcInstallation: 'DP-Check'
                dependencyCheckPublisher pattern: '**/dependency-check-report.xml'
            }
        }
        stage('TRIVY FS SCAN') {
            steps {
                sh "trivy fs . > trivyfs.txt"
            }
        }
        stage("Docker Build & Push"){
            steps{
                script{
                   withDockerRegistry(credentialsId: 'docker', toolName: 'docker'){   
                       sh "docker build -t tetrisv2 ."
                       sh "docker tag tetrisv2 bhushann11/tetrisv2:latest "
                       sh "docker push bhushann11/tetrisv2:latest "
                    }
                }
            }
        }
        stage("TRIVY"){
            steps{
                sh "trivy image bhushann11/tetrisv2:latest > trivyimage.txt" 
            }
        }
        stage('Manifest Checkout Code') {
            steps {
                git branch: 'main', url: 'https://github.com/Bhushan0151/Tetris-manifest.git'
            }
        }
        stage('Update Deployment File') {
            steps {
                script {
                    withCredentials([string(credentialsId: 'github', variable: 'GITHUB_TOKEN')]) {
                       NEW_IMAGE_NAME = "bhushann11/tetrisv2:latest"  // update your image here
                       sh "sed -i 's|image: .*|image: $NEW_IMAGE_NAME|' deployment.yml"
                       sh 'git add deployment.yml'
                       sh "git commit -m 'Update deployment image to $NEW_IMAGE_NAME'"
                       sh "git push https://${GITHUB_TOKEN}@github.com/${GIT_USER_NAME}/${GIT_REPO_NAME} HEAD:main"
                    }
                }
            }
        }
    }
}

Click on Apply and build

Stage view

To see the report, you can go to Sonarqube Server and go to Projects

When you log in to Dockerhub, you will see a new image is created

If you go to Argo CD Now it will automatically update is available of the version 2 image

So we have to sync this, we will get output, with same link- we run the job or play the game with the same link

OUTPUT - Version-2.0

Last updated