# Part 2: Install Jenkins Master, Slave & Tools

**What will we set up in this part?**

*   **Jenkins Master**
    
*   **Jenkins Slave**
    
*   **EKS**
    
*   **SonarQube**
    
*   **ArgoCD**
    
*   **Trivy**
    

* * *

> \[Note\] This project will be implemented in the **Singapore** region (ap-southeast-1).

### **Setting up the Jenkins Master**

*   **Spinup AWS EC2 instances with 2CPU, 8GB of RAM (t2.large), and 30 GB of storage, and install Docker on them.**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/d7282dcd-22d2-4705-9f7a-a423a94a612a.png align="center")

*   **Open the ports below in the security group of the master machine, and also attach the same security group to the Jenkins worker node (We will create the worker node shortly)**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/097d603f-6f84-4ffd-80c3-d317ee84d953.png align="center")

*   **Install Java**
    

```shell
sudo apt update
sudo apt install openjdk-21-jre-headless
java -version
```

```shell
openjdk 21.0.8 2025-07-15
OpenJDK Runtime Environment (build 21.0.8+9-Debian-1)
OpenJDK 64-Bit Server VM (build 21.0.8+9-Debian-1, mixed mode, sharing)
```

*   **Install and configure** [**Jenkins**](https://github.com/abhinandan-chougule/devops-tools-install/blob/main/Jenkins/jenkins.sh) **(Master machine)**
    

```shell
sudo wget -O /etc/yum.repos.d/jenkins.repo \
    https://pkg.jenkins.io/rpm-stable/jenkins.repo
sudo dnf upgrade

# Add required dependencies for the Jenkins package
sudo dnf install jenkins
sudo systemctl daemon-reload 
```

*   **Start Jenkins. You can enable the Jenkins service to**
    

```shell
#start at boot with 
sudo systemctl enable jenkins 

#start the Jenkins service 
sudo systemctl start jenkins 

#check the status of the Jenkins service
sudo systemctl status Jenkins
```

**Get your password from**

```shell
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
```

*   **Now, access the Jenkins Master in your browser using the EC2 public IP on port 8080 and configure it.**
    
*   **Install suggested plugins**
    

> Note - If we install suggested pugins then it may slows down Jenkins UI

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/7b894adf-b87b-4d01-ae51-1b9378f1b990.png align="center")

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/dde83db6-7ad4-44a8-b491-21571234841f.png align="center")

*   **Create an admin user to manage Jenkins**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/b5f340b7-2027-4e79-893a-638d13c95db7.png align="center")

*   **Create AWS IAM-->user-->Create user and then create Access Key**
    

Ex.  
Access ID: AKIAZDZTBOHGUD5KKPX3  
Secret access key • uPBtoXTLltBRhxoMs8IdfUzQM42LAASsm9nzOgQa

*   **AWS CLI and configure on Jenkins Master (Setup** [**AWSCLI**](https://github.com/abhinandan-chougule/devops-tools-install/blob/main/AWSCLI/AWSCLI.sh)**)**
    

```shell
"https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
    sudo apt install unzip
    unzip awscliv2.zip
    sudo ./aws/install
    aws configure
```

*   **Check AWS connectivity**
    

```shell

aws sts get-caller-identity
```

*   **Install kubectl (Master machine) (Setup kubectl )**
    

```shell
    curl -o kubectl https://amazon-eks.s3.us-west- 2.amazonaws.com/1.19.6/2021-01-05/bin/linux/amd64/kubectl
    chmod +x ./kubectl
    sudo mv ./kubectl /usr/local/bin
    kubectl version --short --client
```

*   **Install eksctl (Master machine) (Setup eksctl)**
    

```shell
    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
```

*   **Create EKS Cluster (Master machine)**
    
*   > Note It may take several minutes to create **a** new cluster
    

```shell
    eksctl create cluster --name=wandercluster \
    --region=ap-south-1 \
    --version=1.30 \
    --without-nodegroup
```

*   **Associate IAM OIDC Provider (Master machine)**
    

```plaintext
    eksctl utils associate-iam-oidc-provider \
    --region ap-south-1 \
    --cluster wandercluster \
    --approve
```

*   **Create Nodegroup (On Jenkins Master)**
    

```plaintext
    eksctl create nodegroup --cluster=wandercluster \
    --region=ap-southeast-1 \
    --name=wandercluster \
    --node-type=t2.large \
    --nodes=2 \
    --nodes-min=2 \
    --nodes-max=2 \
    --node-volume-size=29 \
    --ssh-access \
    --ssh-public-key=my-devops-key
```

### **Install and configure SonarQube (On the Master node)**

```shell
docker run -itd --name SonarQube-Server -p 9000:9000 sonarqube:lts-community
```

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/2a19c2bb-5542-46be-90a2-a1146c0ca2c7.png align="center")

*   **Access the Sonarqube server on:** `public-ip-of-jenkins-master:9000`
    

> Note- Initial username= **admin** and password= **admin**

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/19191e6b-0550-4775-9c61-85b382e7752f.png align="center")

### Install and Configure ArgoCD (On the Jenkins Master)

*   **Create argocd namespace**
    

```plaintext
kubectl create namespace argocd
```

*   **Apply the argocd manifest**
    

```plaintext
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
```

*   **Make sure all pods are running in the argocd namespace**
    

```plaintext
watch kubectl get pods -n argocd
```

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/66ddc2fa-13d2-4c4e-a523-cd7e72762c0d.png align="center")

*   **Install argocd CLI**
    

```plaintext
sudo curl --silent --location -o /usr/local/bin/argocd https://github.com/argoproj/argo cd/releases/download/v2.4.7/argocd-linux-amd64
```

*   **Provide executable permission**
    

```plaintext
sudo chmod +x /usr/local/bin/argocd
```

*   **Verify argocd**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/43ba9325-46d0-48b9-8fda-2697c686bbc1.png align="center")

*   **Check argocd services**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/3daa25e0-8893-4d41-8f62-9215bfc1e8a9.png align="center")

*   **Change the argocd server's service from <mark class="bg-yellow-200 dark:bg-yellow-500/30">ClusterIP</mark> to <mark class="bg-yellow-200 dark:bg-yellow-500/30">NodePort</mark>**
    

```plaintext
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort"}}'
```

**Or you can manually edit the manifest file also by going inside it, using this command:**

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/2f24980f-eccb-47df-ba6e-81198627f5fa.png align="center")

*   **Confirm service is patched or not**
    

```shell
kubectl get svc -n argocd
```

*   **Check the port where the ArgoCD server is running and expose it on the security groups of a worker node**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/9f70945d-323f-4d29-a054-5ca5438d0ab2.png align="center")

**port: 31797**

*   Access it on the browser, click on advance, and proceed with `public-ip-master-node:317979`
    

> Note: If you find an error like this in the above image, then run the command below:

```shell
kubectl port-forward svc/argocd-server -n argocd 31797:80 --address 0.0.0.0 &
```

*   Page
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/3d95014a-7604-4932-a7da-7eab82d879ad.png align="center")

*   **Fetch the initial password of the argocd server from Jenkins-ci-master**
    

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

**Username**: `admin` •  
**Now, go to User Info and update your argocd password** `wnx0ZrUozW5oZeDq`

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/2780d7c0-0bfd-4338-83ff-3834e2782c55.png align="center")

* * *

### **Setting up Jenkins Slave node**

*   Create a new EC2 instance (Jenkins Slave) with 2CPU, 8GB of RAM (t2.large), and 30 GB of storage, and install Java on it
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/9e99a4de-c794-4f83-8849-03f5d981ca69.png align="center")

```shell
sudo apt update
sudo apt install openjdk-21-jre-headless
java -version
```

*   **Attach the IAM role with administrator access**
    

Create an IAM role with administrator access, and attach it to the Jenkins Slave node. Select Jenkins slave EC2 instance --> Actions --> Security --> Modify IAM role

*   **Configure AWSCLI (Setup** [**AWSCLI**](https://github.com/abhinandan-chougule/devops-tools-install/blob/main/AWSCLI/AWSCLI.sh)**)**
    

```shell
"https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
    sudo apt install unzip
    unzip awscliv2.zip
    sudo ./aws/install
    aws configure
```

*   **\*\*Generate ssh keys (<mark class="bg-yellow-200 dark:bg-yellow-500/30">on the master</mark>) to set up the Jenkins master-slave relation  
    \*\***`ssh-keygen`
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/2c113e12-f29b-4502-aea2-219ba3704c7c.png align="center")

*   **On the <mark class="bg-yellow-200 dark:bg-yellow-500/30">Jenkins Slave node,</mark> move to the directory(.**`ssh`**) where your ssh keys are generated, and copy the content of the public key and paste to authorized\_keys file.**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/7df10a62-42c7-4117-9d44-42d12887885e.png align="center")

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/0f558dc7-4681-47e3-a374-b098600bcb4e.png align="center")

*   **Now, go to the Jenkins master and navigate to Manage Jenkins --> Nodes, and click on New node**
    

Name: Node • `Type: permanent agent`  
Number of executors: `2`  
Remote root directory: `/home/ubuntu`  
Labels: `Node`  
Usage: `Only build jobs with label expressions matching this node`  
Launch method: `Via ssh`  
Host: `public ip of Jenkins slave`

**Manage Jenkins---> Credentials**: `Add --> Kind: ssh username with private key --> ID: Worker --> Description: Worker --> Username: ubuntu --> Private key: Enter directly --> Add Private key`

Host Key Verification Strategy: Non`-Verifying Verification Strategy`  
Availability: `Keep this agent online as much as possible`

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/eca108ee-a30f-412b-b7d1-d93c7d17e2b0.png align="center")

> Note: the public IP should be the master’s instance-generated private, which is stored in id\_ed25519.

*   **And your Jenkins slave node is added**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/b12d2a05-7b73-4442-9ffd-ec01126f16b2.png align="center")

> If any error occurs, open the settings icon of the Node and make changes, then launch the agent again.

*   **Install Docker (Jenkins slave)**
    

```shell
sudo apt install docker.io -y
sudo usermod -aG docker ubuntu && newgrp docker
```

### Install Trivy (On the Jenkins slave)

```shell
sudo apt-get install wget apt-transport-https gnupg lsb-release -y
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 -y
sudo apt-get install trivy -y
```

* * *

### Steps to add email notification

*   If not yet, then -> Go to your Jenkins Master EC2 instance and allow for SMTPS
    
*   Now, we need to generate an application password from our Gmail account to authenticate with Jenkins
    
*   Open Gmail and go to Manage your Google Account --> Security
    

> Note- \[Important\] Make sure 2-step verification is on

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/c81da363-643c-49d7-8828-a8a8144b0eb5.png align="center")

*   ### Search for the App password and create an app password for Jenkins
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/b11a8dca-093d-4ce6-9824-6cb62bf18549.png align="center")

> Note- App password will be in this form "atqw gvjh ifrr wdkf" make sure when you enter in jenkins it should have no <mark class="bg-yellow-200 dark:bg-yellow-500/30">space</mark> between them like "atqwgvjhifrrwdkf"

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/f93d8597-ba0d-4787-b4e1-322f765618e8.png align="center")

*   **Once the app password is created, go back to Jenkins, Manage Jenkins --> Credentials to add username and password for email notification**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/1a903088-4b6f-43ba-9ad3-10ddd384d264.png align="center")

*   **Go back to Manage Jenkins --> System and search for Extended E-mail Notification and set up email notification**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/0c730a40-df99-4dcd-993e-39c8b718ab9c.png align="center")

*   **\[Important\] Enter your Gmail password, which we copied recently, in the password field E-mail Notification --> Advanced**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/0124253e-16ab-49b5-ac0e-28f3c81c7f39.png align="center")

*   **Verify if the test email was received (Jenkins to Gmail setup successful)**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/0ee301bf-c35a-4b13-8629-7a8ada497c28.png align="center")

> The next configuration is in Part 3

* * *

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><a target="_blank" rel="noopener noreferrer nofollow" class="text-primary underline underline-offset-2 hover:text-primary/80 cursor-pointer" href="https://hashnode.com/edit/cmmbp8z5z001q2ep59qx48tfe" style="pointer-events: none;">Part 3: Tools Integration with Jenkins</a></div>
</div>
