Overview:
This project implements a fully automated CI/CD pipeline using Jenkins to streamline the deployment of a Node.js application on AWS ECS. The pipeline ensures code quality, security, and high availability by integrating SonarQube, OWASP Dependency-Check, Docker, AWS ECR, and ECS. Additionally, Elastic Load Balancer (ELB) is used to distribute traffic efficiently.
Key Features & Workflow:
✅ Code Fetching: Jenkins pulls the latest source code from GitHub.
✅ Code Quality Analysis: SonarQube scans the code for vulnerabilities & maintainability issues.
✅ Security Scan: OWASP Dependency-Check detects security vulnerabilities in dependencies.
✅ Build & Packaging: Dependencies are installed using npm.
Docker image is built and tagged with a unique build number.
✅ Docker Image Push: The image is securely pushed to AWS Elastic Container Registry (ECR).
✅ AWS ECS Deployment: The application is deployed as a container on AWS ECS (Fargate/EC2).The service is restarted using force-new-deployment to fetch the latest image.
✅ Traffic Management: The ECS service is connected to an Elastic Load Balancer (ELB) for high availability & traffic distribution.
✅ Automated Rollouts: If a deployment fails at any stage, Jenkins stops the pipeline to prevent bad code from reaching production.
Steps:
Step 1 : Launch 2 instance on AWS EC2 of t2medium type
- one for Jenkins
- another for SonarQube
Step 2 : install docker in both of them
#!/bin/bash
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
sudo usermod -aG docker $USER && newgrp docker
or
sudo apt update
sudo apt install docker.io -y
sudo usermod -aG docker $USER && newgrp docker
Step 3 : Install Jenkins in one Inststance
for installing Jenkins
https://dev.to/bhaktraj/how-to-install-jenkins-in-ubuntu-2735
or
#!/bin/bash
sudo apt update
sudo apt install openjdk-21-jre-headless -y
sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \
https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]" \
https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
/etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins -y
sudo systemctl enable jenkins
sudo systemctl start jenkins
Once Jenkins is installed, you will need to go to your AWS EC2 Security Group and open Inbound Port 8080, since Jenkins works on Port 8080.
Now, grab your Public IP Address
url = http://ec2_public_IPaddress:8080
for password
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
after that set the jenkins
Step 4 : Run SonarQube container on another Instance
docker run -d --name sonar -p 9000:9000 --restart always sonarqube:lts-community
once SonarQube is running you will need to allow inbound rule for port 9000 in EC2 security group, since SonarQube running on 9000 port
url = http://ec2_public_IPaddress:9000
username = admin
password = admin
Step 5 : Install Plugins like JDK, Sonarqube Scanner, NodeJs, OWASP Dependency Check, docker AWS on Jenkins
Goto Manage Jenkins →Plugins → Available Plugins →
Install Plugin
- SonarQube Scanner
- NodeJs Plugin
- Install OWASP Dependency Check
- Docker
- Docker Commons
- Docker Pipeline
- Docker API
- docker-build-step
- AWS Steps
- AWS Credentials
- Amazon Web Services SDK :: All
5.1 Configure Java and Nodejs in Global Tool Configuration
- Goto Manage Jenkins → Tools → Install JDK(17) and NodeJs(16)→ Click on Apply and Save
Step 6 : Configure Sonar Server in Manage Jenkins
Grab the Public IP Address of your EC2 Instance, Sonarqube works on Port 9000, so :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
copy Token
Goto Jenkins Dashboard → Manage Jenkins → Credentials → Add Secret Text.
Now, go to Dashboard → Manage Jenkins → System and Add Server url , name and and authentication credation
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.
Step 7 : we had to configure the Tool OWASP Dependency Check
Goto Dashboard → Manage Jenkins → Tools →
Step 8 : Now go configure → Pipeline and add this stage to your pipeline and build.
pipeline {
agent any
tools {
jdk 'jdk17'
nodejs 'node16'
}
environment {
scannerhome = tool 'sonarserver'
imagename = '058264453864.dkr.ecr.us-east-1.amazonaws.com/nodejsapp'
awscred = 'ecr:us-east-1:awscred'
registeryurl='https://058264453864.dkr.ecr.us-east-1.amazonaws.com/nodejsapp'
cluster='nojejsproject'
service='nodejsprojectservice'
}
stages{
stage('clean workspace'){
steps{
cleanWs()
}
}
stage("Fetch Code"){
steps{
git url: 'https://github.com/bhaktraj/zomatocicd.git', branch:'main'
}
}
stage("Sonarqube analyse "){
steps{
withSonarQubeEnv('sonarserver') {
sh '''$scannerhome/bin/sonar-scanner -Dsonar.projectName=zomato \
-Dsonar.projectKey=zomato '''
}
}
}
stage("Quality Gate") {
steps {
timeout(time: 1, unit: 'MINUTES') {
// Parameter indicates whether to set pipeline to UNSTABLE if Quality Gate fails
// true = set pipeline to UNSTABLE, false = don't
waitForQualityGate abortPipeline: true
}
}
}
stage("install Dependences"){
steps{
sh 'npm install'
}
}
stage('OWASP Dependency-Check') {
steps {
dependencyCheck additionalArguments: '''
-o './'
-s './'
-f 'ALL'
--prettyPrint''', odcInstallation: 'owasp'
dependencyCheckPublisher pattern: 'dependency-check-report.xml'
}
}
}
}
Step 9 : Create IAM User on aws cloud and provide permission of awsECSFullaccess
and create access key
Step 10 : Configure AWS Credential
Goto Jenkins Dashboard → Manage Jenkins → Credentials
select aws Credential and then and fill out access key and access id
also install aws cli in server by cmd
sudo apt update
sudo snap install aws-cli --classic
Step 11 : Configure ECR On AWS cloud
Step 12 : Configure ECS On AWS Cloud
Step 13 : now set Pipeline or update it
pipeline {
agent any
tools {
jdk 'jdk17'
nodejs 'node16'
}
environment {
scannerhome = tool 'sonarserver'
imagename = '058264453864.dkr.ecr.us-east-1.amazonaws.com/nodejsapp'
awscred = 'ecr:us-east-1:awscred'
registeryurl='https://058264453864.dkr.ecr.us-east-1.amazonaws.com/nodejsapp'
cluster='nojejsproject'
service='nodejsprojectservice'
}
stages{
stage('clean workspace'){
steps{
cleanWs()
}
}
stage("Fetch Code"){
steps{
git url: 'https://github.com/bhaktraj/zomatocicd.git', branch:'main'
}
}
stage("Sonarqube analyse "){
steps{
withSonarQubeEnv('sonarserver') {
sh '''$scannerhome/bin/sonar-scanner -Dsonar.projectName=zomato \
-Dsonar.projectKey=zomato '''
}
}
}
stage("Quality Gate") {
steps {
timeout(time: 1, unit: 'MINUTES') {
// Parameter indicates whether to set pipeline to UNSTABLE if Quality Gate fails
// true = set pipeline to UNSTABLE, false = don't
waitForQualityGate abortPipeline: true
}
}
}
stage("install Dependences"){
steps{
sh 'npm install'
}
}
stage('OWASP Dependency-Check') {
steps {
dependencyCheck additionalArguments: '''
-o './'
-s './'
-f 'ALL'
--prettyPrint''', odcInstallation: 'owasp'
dependencyCheckPublisher pattern: 'dependency-check-report.xml'
}
}
stage('Build docker images'){
steps{
script{
dockerimage = docker.build(imagename + ":$BUILD_NUMBER", ".")
}
}
}
stage('Upload to ECR'){
steps{
script{
docker.withRegistry(registeryurl, awscred){
dockerimage.push("$BUILD_NUMBER")
dockerimage.push("latest")
}
}
}
}
stage('deploy to ecs'){
steps{
withAWS(credentials:'awscred', region:'us-east-1'){
sh 'aws ecs update-service --cluster ${cluster} --service ${service} --force-new-deployment'
}
}
}
}
}
Top comments (0)