- Install the required plugins and configure tools
- Configure credentials (GitHub, DockerHub, gmail, sonarqube)
- Configure Jenkins with SonarQube server
- Configure SMTP server on Jenkins for sending email notfications
- Generate API Key from TMDB
First, We need to provision a jump server where can execute all kubernetes related commands. Then, provision Jenkins server for CI pipeline and SonarQube server for static code analysis. To do so, I have created a Terraform code that provisions all these three servers. The Terraform code will install the AWS cli, kubectl, and eksctl on the jump server, JAVA and jenkins on the Jenkins server, and will also install sonarqube docker image on the SonarQube server. To run the terraform code, navigate to Terraform/Jenkins-SonarQube-Jump-Server folder, and then run the follwing commands:
terraform init
terraform plan
terraform apply --auto-approveTo provisiong an EKS cluster, navigate to Terraform/EKS folder and run the following commands:
terraform init
terraform plan
terraform apply --auto-approveGo to Jenkins -> Manage Jenkins -> Plugins -> Available plugins, and install the follwoing plugins:
- Eclipse Temurin installer Plugin
- NodeJS Plugin
- SonarQube Scanner for Jenkins Version
- OWASP Dependency-Check Plugin
- Docker API Plugin, Docker Commons Plugin, Docker Pipeline, Docker plugin
After plugins installation, configure the tools as follow:
- GitHub
step 1: Generate GitHub token
Go to your GitHub account > settings > Developer settings > personal access tokens > Token classic > Generate new token.
step 2: Configure the generated token on Jinkins
Go to Jenkins > Manage Jenkins > Credentials > Add Credentials. In the username and password filed, enter your Github account username and the generated token. - DockerHub
Go to Jenkins > Manage Jenkins > Credentials > Add Credentials. Add your Dockerhub username and password. - mail
step 1: Generate token on gmail
Go to your gmail account -> Manage your Google Account -> Security -> 2-Step Verification -> App passwords. Enter yourApp namethen enter create. Copy the generated token.
step 2: Configure the generated token on Jenkins
Go to Jenkins > Manage Jenkins > Credentials > Add Credentials. In the username and password filed, enter your gmail address and the generated gmail token. - SonarQube
step 1: Generate SonarQube token
Go to SonarQube server > Administration > Security > Users > Tokens. Enter yourtoken-name, Generate, and then Done. step 2: Configure SonarQube token on Jenkins
Go to Jenkins > Manage Jenkins > Credentials > Add Credentials. Select secret text and place the sonarqube token.
To integrate SonarQube server with Jenkins server. Go to your Jenkins server > Manage Jenkins > System. Scroll down to SonarQube Servers. Add the following enteries:
Configure webhook on SonarQube. Go to your SonarQube server > Administration > configuration > Webhooks > Create.

We need to configure SMTP server on Jenkins for sending email notfications. We'll send email about trivy filesystem and image scan. To configure SMTP server, go to your Jenkins server > Manage Jenkins > System. Scroll down to Extended E-mail Notification.
Then Scroll down to Default Triggers and check the following:
Finally, scroll down to E-mail Notification and set the following settings:

Go to https://www.themoviedb.org/ > Login > Click here. Fill up your details, go to API, generate API Key, copy the API Key, and then use the key for building docker image.
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt update
sudo apt install -y helmkubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yamlTo get Argo CD initial-admin password, run the following command.
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -dTo access Argo CD UI, change Argo CD server service to loadbalancer.
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'To install AWS LoadBalancer Controller on EKS cluster follow the steps:
step 1: Create IAM Policy for AWS Loadbalancer controller.
curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.2.1/docs/install/iam_policy.json
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam-policy.jsonstep 2: Create iamserviceaccount. Replace your-account-id with your real account ID.
eksctl create iamserviceaccount \
--cluster=eks-dev \
--namespace=kube-system \
--name=aws-load-balancer-controller \
--attach-policy-arn=arn:aws:iam::[your-account-id]:policy/AWSLoadBalancerControllerIAMPolicy \
--override-existing-serviceaccounts \
--approvestep 3: Install AWS Loadbalancer controller with helm. Replace region with your default region in AWS and your-vpc-id with your eks's vpc id.
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system \
--set clusterName=eks-dev \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--set region=eu-west-1 \
--set vpcId=[your-vpc-id]step 1: Create IAM policy for ExternalDNS
The following IAM Policy document allows ExternalDNS to update Route53 Resource Record Sets and Hosted Zones. Create IAM policy name AllowExternalDNSUpdates (but you can name it whatever you prefer).
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets"
],
"Resource": [
"arn:aws:route53:::hostedzone/*"
]
},
{
"Effect": "Allow",
"Action": [
"route53:ListHostedZones",
"route53:ListResourceRecordSets",
"route53:ListTagsForResource"
],
"Resource": [
"*"
]
}
]
}If you are using the AWS CLI, you can run the following to install the above policy (saved as policy.json).
aws iam create-policy --policy-name "AllowExternalDNSUpdates" --policy-document file://policy.jsonstep 2: Create iamserviceaccount for ExternalDNS. Replace Your-account-id with you real AWS account ID.
eksctl create iamserviceaccount \
--cluster eks-dev \
--name "external-dns" \
--namespace default \
--attach-policy-arn arn:aws:iam::[Your-account-id]:policy/AmazonExternalDnsPolicy \
--approvestep 3: Create ExternalDns yaml file, name it externaldns.yml (but you can name it whatever you want), and copy the following manifest
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: external-dns
rules:
- apiGroups: [""]
resources: ["services","endpoints","pods"]
verbs: ["get","watch","list"]
- apiGroups: ["extensions","networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get","watch","list"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list","watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: external-dns-viewer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
# If you're using kiam or kube2iam, specify the following annotation.
# Otherwise, you may safely omit it. #Change-2: Commented line 55 and 56
#annotations:
#iam.amazonaws.com/role: arn:aws:iam::ACCOUNT-ID:role/IAM-SERVICE-ROLE-NAME
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
image: k8s.gcr.io/external-dns/external-dns:v0.10.2
args:
- --source=service
- --source=ingress
# Change-3: Commented line 65 and 67 - --domain-filter=external-dns-test.my-org.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
- --provider=aws
# Change-3: Commented line 65 and 67 - --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
- --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both)
- --registry=txt
- --txt-owner-id=my-hostedzone-identifier
securityContext:
fsGroup: 65534 # For ExternalDNS to be able to read Kubernetes and AWS token filesstep 4: Deploy ExternalDns on EKS cluster
kubectl create -f externaldns.ymlStep 1: Add the Helm chart repository for Prometheus and Grafana:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo updateStep 2: Install Prometheus Stack
helm install prometheus-stack prometheus-community/kube-prometheus-stack --namespace monitoring --create-namespaceStep 3: Access Grafana Dashboard
kubectl patch svc prometheus-stack-grafana -n monitoring -p '{"spec": {"type": "LoadBalancer"}}'







