> For the complete documentation index, see [llms.txt](https://bhushans-devops-organization.gitbook.io/advanced-projects/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bhushans-devops-organization.gitbook.io/advanced-projects/amazon-app-deployment-a-devsecops-approach-with-terraform-and-jenkins-ci-cd-or-docker-or.md).

# Amazon App Deployment: A DevSecOps Approach with Terraform and Jenkins CI/CD | Docker |

<figure><img src="/files/RTXbwvoB8jLQanjHT7eP" alt="" width="563"><figcaption></figcaption></figure>

#### <mark style="color:orange;">Git Hub Link :</mark> &#x20;

```
https://github.com/Bhushan0151/Amazon-FE.git
```

### Use the below Blog to install Terraform and Aws cli

AWS CLI - <https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html>

Terraform - <https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli>

<figure><img src="/files/NQgkFqARav4TW7Nrd9SW" alt=""><figcaption></figcaption></figure>

## **Step1: create an IAM user** <a href="#heading-step1-create-an-iam-user" id="heading-step1-create-an-iam-user"></a>

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 this checkbox with Administrator access -> Click "Next" -> Click "Create user" -> Click newly created user -> Click "Security credentials" -> Click "Create access key" ->  Click this radio button with the CLI -> Agree to terms  ->  Click Next   ->  Download .csv file &#x20;

<figure><img src="/files/5dJp9Odcn2KxAuFdU2Pm" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/uTeT1NWjnZaIr9TiTv1V" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/U79GOyDpXlIas92OZWZi" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/IPOpo2xqzJYb5Az2rVKg" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/Vckx5MvHwvAepcxoXGO5" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/wKuTMKeECIX1M899oIFb" alt=""><figcaption></figcaption></figure>

## Step2: Aws Configure <a href="#heading-step2-aws-configure" id="heading-step2-aws-configure"></a>

Go to vs code or Cmd your wish

```
aws configure
```

<figure><img src="/files/WZd1hBuMprmpajCusqBA" alt=""><figcaption></figcaption></figure>

Provide your Aws Access key and Secret Access key

## Step3: Terraform files and Provision Jenkins,sonar <a href="#heading-step3-terraform-files-and-provision-jenkinssonar" id="heading-step3-terraform-files-and-provision-jenkinssonar"></a>

### main.tf

<figure><img src="/files/GwpAg0DS0stUech7Kpx6" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/V9NEh8AtRgJ6LvKWPC9X" alt=""><figcaption></figcaption></figure>

````
```
resource "aws_instance" "web" {
  ami                    = "ami-07b36ea9852e986ad"     #change ami id for different region
  instance_type          = "t2.large"
  key_name               = "Ohio-pem"
  vpc_security_group_ids = [aws_security_group.Jenkins-sg.id]
  user_data              = templatefile("./install.sh", {})

  tags = {
    Name = "Jenkins-sonarqube"
  }

  root_block_device {
    volume_size = 30
  }
}

resource "aws_security_group" "Jenkins-sg" {
  name        = "Jenkins-sg"
  description = "Allow TLS inbound traffic"

  ingress = [
    for port in [22, 80, 443, 8080, 9000, 3000] : {
      description      = "inbound rules"
      from_port        = port
      to_port          = port
      protocol         = "tcp"
      cidr_blocks      = ["0.0.0.0/0"]
      ipv6_cidr_blocks = []
      prefix_list_ids  = []
      security_groups  = []
      self             = false
    }
  ]

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "jenkins-sg"
  }
}

```
````

### provider.tf

```

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

# Configure the AWS Provider
provider "aws" {
  region = "us-east-2"
}

```

<figure><img src="/files/lMzjoRbQZrZmXbUyYXbv" alt=""><figcaption></figcaption></figure>

### install.sh

```
#!/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

```

<figure><img src="/files/ofW74fLYA5sqAvB7Isxm" alt=""><figcaption></figcaption></figure>

## **Terraform commands to provision**

```
terraform init
terraform validate
terraform plan
terraform apply

```

<figure><img src="/files/v7yENBsCFrbhHAfHLoDH" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/AveeT0JOEJKi99yLmnGR" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/KQb1a1wnT4xw2lXsKXGx" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/6mnPl6AfLFAHAtiEJLj9" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/29Y1Hg8VydkxHXOlepww" alt=""><figcaption></figcaption></figure>

### <mark style="color:green;">**OUTPUT**</mark>**&#x20;**<mark style="color:purple;">**-**</mark>

<figure><img src="/files/6aGBCSB34AwN1OrNclCH" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/qlQrw5OUyed31BRMf2se" alt=""><figcaption></figcaption></figure>

```
<instance-ip:8080> #jenkins
```

<figure><img src="/files/f539U0yxe4H0fQr0wwyB" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/TRFeryQRHiP35JmFU7gL" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/mGMTmwP0hdpHdu8lmy1n" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/ArCgdJKnKT4iYd57c5nL" alt=""><figcaption></figcaption></figure>

**SonarQube -**

Copy your Public key again and paste it into a new tab

```
<instance-public-ip:9000
```

Enter username and password, click on login and change password

```
username admin
password admin    
```

<figure><img src="/files/cfSqH7owiRUW28ohfMAP" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/HqWTiaAu6CsNqxPA3gMM" alt=""><figcaption></figcaption></figure>

**Check trivy version**

```
trivy --version
```

## **Step 4 — Install Plugins like JDK, Sonarqube Scanner, NodeJs, OWASP Dependency Check** <a href="#heading-step-4-install-plugins-like-jdk-sonarqube-scanner-nodejs-owasp-dependency-check" id="heading-step-4-install-plugins-like-jdk-sonarqube-scanner-nodejs-owasp-dependency-check"></a>

### **4A — Install Plugin** <a href="#heading-4a-install-plugin" id="heading-4a-install-plugin"></a>

Goto Manage Jenkins →Plugins → Available Plugins →

Install below plugins

1 → Eclipse Temurin Installer (Install without restart)

2 → SonarQube Scanner (Install without restart)

3 → NodeJs Plugin (Install Without restart)

<figure><img src="/files/xYjIHqcR1U3gauGx3ZPh" alt=""><figcaption></figcaption></figure>

### **4B — Configure Java and Nodejs in Global Tool Configuration** <a href="#heading-4b-configure-java-and-nodejs-in-global-tool-configuration" id="heading-4b-configure-java-and-nodejs-in-global-tool-configuration"></a>

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

<figure><img src="/files/CVuhvV1dvZXbNW95cbGv" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/dyuV1Z7vt8e075qIsutZ" alt=""><figcaption></figcaption></figure>

## **Step 5 — Configure Sonar Server in Manage Jenkins** <a href="#heading-step-5-configure-sonar-server-in-manage-jenkins" id="heading-step-5-configure-sonar-server-in-manage-jenkins"></a>

Grab the Public IP Address of your EC2 Instance, SonarQube works on Port 9000, so \<Public IP>:9000.&#x20;

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

<figure><img src="/files/6CA5NPt2go7UcbjCClp4" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/gk2r4lIwfL9N7uBf7v1n" alt=""><figcaption></figcaption></figure>

Goto Jenkins Dashboard → Manage Jenkins → Credentials → Add Secret Text. It should look like this

<figure><img src="/files/FSdH9LaeCCc3YaFAFEAZ" alt=""><figcaption></figcaption></figure>

Now, go to Dashboard → Manage Jenkins → System and Add like the below image.

<figure><img src="/files/EEHHx8Xj3xzYxhjbm2I9" alt=""><figcaption></figcaption></figure>

Click on Apply and Save

**The Configure System option** is used in Jenkins to configure different server

**Global Tool Configuration** is used to configure different tools that we install using Plugins

We will install a sonar scanner in the tools.

<figure><img src="/files/5n9BnflxqvUwjoh8rBdf" alt=""><figcaption></figcaption></figure>

In the Sonarqube Dashboard add a quality gate also

Administration--> Configuration-->Webhooks

<figure><img src="/files/ukn9Ra23yxuLQWjgS8sx" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/JeQk2nUSFk0LDE0HcRB4" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/qkXVODyTDjuSepPVD93N" alt=""><figcaption></figcaption></figure>

```
#in url section of quality gate

<http://jenkins-public-ip:8080>/sonarqube-webhook/
```

### Let's go to our Pipeline and add the script in our Pipeline Script.

```
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/Amazon-FE.git'
            }
        }
        stage("Sonarqube Analysis "){
            steps{
                withSonarQubeEnv('sonar-server') {
                    sh ''' $SCANNER_HOME/bin/sonar-scanner -Dsonar.projectName=Amazon \
                    -Dsonar.projectKey=Amazon '''
                }
            }
        }
        stage("quality gate"){
           steps {
                script {
                    waitForQualityGate abortPipeline: false, credentialsId: 'Sonar-token' 
                }
            } 
        }
        stage('Install Dependencies') {
            steps {
                sh "npm install"
            }
        }
    }
}

```

### Click on Build now, you will see the stage view like this

<figure><img src="/files/RUpEm7l5QdTgLbpjx2Wh" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/49oxWxau4BnMbt9Lwqqx" alt=""><figcaption></figcaption></figure>

## **Step 6 — Install OWASP Dependency Check Plugins** <a href="#heading-step-6-install-owasp-dependency-check-plugins" id="heading-step-6-install-owasp-dependency-check-plugins"></a>

GotoDashboard → Manage Jenkins → Plugins → OWASP Dependency-Check. Click on it and install it without restart.

<figure><img src="/files/eGhawWeeKg2nXG7r3w8s" alt=""><figcaption></figcaption></figure>

### First, we configured the Plugin and next, we had to configure the Tool

Goto Dashboard → Manage Jenkins → Tools →

<figure><img src="/files/ANhezzX8ZZ9ZPTmsjF41" alt=""><figcaption></figcaption></figure>

Click on Apply and Save here.

### Now go configure → Pipeline and add this stage to your pipeline and build.

```
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"
            }
        }

```

<figure><img src="/files/vPpbGhTFPVbqWbugmC3B" alt=""><figcaption></figcaption></figure>

### The stage view would look like this,

<figure><img src="/files/o3CXu8eKhyBnAQoIZqTh" alt=""><figcaption></figcaption></figure>

## **Step 7 — Docker Image Build and Push** <a href="#heading-step-7-docker-image-build-and-push" id="heading-step-7-docker-image-build-and-push"></a>

We need to install the Docker tool in our system, Goto Dashboard → Manage Plugins → Available plugins → Search for Docker and install these plugins

`Docker`

`Docker Commons`

`Docker Pipeline`

`Docker API`

`docker-build-step`

and click on install without restart

<figure><img src="/files/uXgSI8Cx5ToqfEs3OuAB" alt=""><figcaption></figcaption></figure>

Now, goto Dashboard → Manage Jenkins → Tools →

<br>

<figure><img src="/files/aHKnushi1c9d4G4IvboM" alt=""><figcaption></figcaption></figure>

Add DockerHub Username and Password under Global Credentials

<figure><img src="/files/GWdyuuwUYlcPlvkw30Ra" alt=""><figcaption></figcaption></figure>

### Add this stage to Pipeline Script

```
stage("Docker Build & Push"){
            steps{
                script{
                   withDockerRegistry(credentialsId: 'docker', toolName: 'docker'){   
                       sh "docker build -t amazon ."
                       sh "docker tag amazon bhushann11/amazon:latest "
                       sh "docker push bhushann11/amazon:latest "
                    }
                }
            }
        }
        stage("TRIVY"){
            steps{
                sh "trivy image bhushann11/amazon:latest > trivyimage.txt" 
            }
        }

```

#### Stage View -

<figure><img src="/files/qHFoptMD4izBlyfJg6b5" alt=""><figcaption></figcaption></figure>

You will see the output below, with a dependency trend.

<figure><img src="/files/82sgRYVSkfpvR0683Shf" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/CxFZtB4WkjdLsNAQ7LA6" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/cAJr14KbtSdP66GpcWG4" alt=""><figcaption></figcaption></figure>

Now Run the container to see if the game coming up or not by adding the below stage

```
stage('Deploy to container'){
            steps{
                sh 'docker run -d --name amazon -p 3000:3000 bhushann11/amazon:latest'
            }
        }

```

### Stage view

<figure><img src="/files/kwStXudodoIcNLr8456F" alt=""><figcaption></figcaption></figure>

```
<Jenkins-public-ip:3000>
```

### You will get this output

<figure><img src="/files/uW1WaXRMKzEH13BvEvqk" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/Pxcq56DOOdheBJxtkYM6" alt=""><figcaption></figcaption></figure>

## Let's destroy everything

Go to VS Code and provide the below command (or) Go to the path where you provisioned the Ec2 instance

```
terraform destroy --auto-approve
```

<figure><img src="/files/VSQ20RwrDzjFsCtwBON8" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/gojItjF7O4HqqEgWAoxu" alt=""><figcaption></figcaption></figure>

### Pipeline&#x20;

```
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/Amazon-FE.git'
            }
        }
        stage("Sonarqube Analysis "){
            steps{
                withSonarQubeEnv('sonar-server') {
                    sh ''' $SCANNER_HOME/bin/sonar-scanner -Dsonar.projectName=Amazon \
                    -Dsonar.projectKey=Amazon '''
                }
            }
        }
        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 amazon ."
                       sh "docker tag amazon bhushann11/amazon:latest "
                       sh "docker push bhushann11/amazon:latest "
                    }
                }
            }
        }
        stage("TRIVY"){
            steps{
                sh "trivy image bhushann11/amazon:latest > trivyimage.txt" 
            }
        }
        
        stage('Deploy to container'){
            steps{
                sh 'docker run -d --name amazon -p 3000:3000 bhushann11/amazon:latest'
            }
        }
    }
}

```
