# 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'
            }
        }
    }
}

```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bhushans-devops-organization.gitbook.io/advanced-projects/amazon-app-deployment-a-devsecops-approach-with-terraform-and-jenkins-ci-cd-or-docker-or.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
