Learn Dev-ops Series-Creating CI/CD pipeline in AWS

Khemlall Mangal
8 min readOct 30, 2022

We will setup CI/CD pipeline for this project and by the end, you will have a fully functional continuous integration pipeline up and running using AWS services.

Architectural Design:

Steps:
1. Login to AWS Account

a) Create a KeyPair
b) Create a Security Group for jenkins and Nexus & sonarqube
c)Create ec2 Instances with Userdata

Creating KeyPair

Go to EC instance and under neworking and security select KeyPair

b) Create a key pair for continuous Integration. Pem format. Example:

Creating Security Group for Jenkins

Add Security group for Nexus …assign 22 to my ip and then 8081 for myip and also jenkins sg

Create Security group for sonar

Edit Jenkins security Group

add port 8080 to have sonar security group attached to it security group

LAUNCH EC2 INSTANCE

SAMPLE PROJECT

Select the CI-Jenkins branch for setup script

Launch Instance: JENKINS SERVER

I choose t2small and not free tier because t2.micro will be too samll and it will hang etc…

Select existing security group and just attached security group to it.

Copy script and paste in the bottom and continue

#!/bin/bashsudo apt updatesudo apt install openjdk-11-jdk -ysudo apt install maven -ycurl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo tee \  /usr/share/keyrings/jenkins-keyring.asc > /dev/nullecho 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/nullsudo apt-get updatesudo apt-get install jenkins -y###

Launch Instance: NEXUS SERVER — Follow same step

select AmazonLinux2 -> t2 medium -> ci keypair

SCRIPT

#!/bin/bash
yum install java-1.8.0-openjdk.x86_64 wget -y
mkdir -p /opt/nexus/
mkdir -p /tmp/nexus/
cd /tmp/nexus/
NEXUSURL="https://download.sonatype.com/nexus/3/latest-unix.tar.gz"
wget $NEXUSURL -O nexus.tar.gz
EXTOUT=`tar xzvf nexus.tar.gz`
NEXUSDIR=`echo $EXTOUT | cut -d '/' -f1`
rm -rf /tmp/nexus/nexus.tar.gz
rsync -avzh /tmp/nexus/ /opt/nexus/
useradd nexus
chown -R nexus.nexus /opt/nexus
cat <<EOT>> /etc/systemd/system/nexus.service
[Unit]
Description=nexus service
After=network.target

[Service]
Type=forking
LimitNOFILE=65536
ExecStart=/opt/nexus/$NEXUSDIR/bin/nexus start
ExecStop=/opt/nexus/$NEXUSDIR/bin/nexus stop
User=nexus
Restart=on-abort

[Install]
WantedBy=multi-user.target
EOTecho 'run_as_user="nexus"' > /opt/nexus/$NEXUSDIR/bin/nexus.rc
systemctl daemon-reload
systemctl start nexus
systemctl enable nexus

Launch Instance: SONAR SERVER

ubuntu 18.2 -> free tier — t2 medium — sonar security group

Script

#!/bin/bash
cp /etc/sysctl.conf /root/sysctl.conf_backup
cat <<EOT> /etc/sysctl.conf
vm.max_map_count=262144
fs.file-max=65536
ulimit -n 65536
ulimit -u 4096
EOT
cp /etc/security/limits.conf /root/sec_limit.conf_backup
cat <<EOT> /etc/security/limits.conf
sonarqube - nofile 65536
sonarqube - nproc 409
EOT
sudo apt-get update -y
sudo apt-get install openjdk-11-jdk -y
sudo update-alternatives --config java
java -versionsudo apt update
wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O - | sudo apt-key add -
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" >> /etc/apt/sources.list.d/pgdg.list'
sudo apt install postgresql postgresql-contrib -y
#sudo -u postgres psql -c "SELECT version();"
sudo systemctl enable postgresql.service
sudo systemctl start postgresql.service
sudo echo "postgres:admin123" | chpasswd
runuser -l postgres -c "createuser sonar"
sudo -i -u postgres psql -c "ALTER USER sonar WITH ENCRYPTED PASSWORD 'admin123';"
sudo -i -u postgres psql -c "CREATE DATABASE sonarqube OWNER sonar;"
sudo -i -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE sonarqube to sonar;"
systemctl restart postgresql
#systemctl status -l postgresql
netstat -tulpena | grep postgres
sudo mkdir -p /sonarqube/
cd /sonarqube/
sudo curl -O https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-8.3.0.34182.zip
sudo apt-get install zip -y
sudo unzip -o sonarqube-8.3.0.34182.zip -d /opt/
sudo mv /opt/sonarqube-8.3.0.34182/ /opt/sonarqube
sudo groupadd sonar
sudo useradd -c "SonarQube - User" -d /opt/sonarqube/ -g sonar sonar
sudo chown sonar:sonar /opt/sonarqube/ -R
cp /opt/sonarqube/conf/sonar.properties /root/sonar.properties_backup
cat <<EOT> /opt/sonarqube/conf/sonar.properties
sonar.jdbc.username=sonar
sonar.jdbc.password=admin123
sonar.jdbc.url=jdbc:postgresql://localhost/sonarqube
sonar.web.host=0.0.0.0
sonar.web.port=9000
sonar.web.javaAdditionalOpts=-server
sonar.search.javaOpts=-Xmx512m -Xms512m -XX:+HeapDumpOnOutOfMemoryError
sonar.log.level=INFO
sonar.path.logs=logs
EOT
cat <<EOT> /etc/systemd/system/sonarqube.service
[Unit]
Description=SonarQube service
After=syslog.target network.target
[Service]
Type=forking
ExecStart=/opt/sonarqube/bin/linux-x86-64/sonar.sh start
ExecStop=/opt/sonarqube/bin/linux-x86-64/sonar.sh stop
User=sonar
Group=sonar
Restart=always
LimitNOFILE=65536
LimitNPROC=4096
[Install]
WantedBy=multi-user.target
EOT
systemctl daemon-reload
systemctl enable sonarqube.service
#systemctl start sonarqube.service
#systemctl status -l sonarqube.service
apt-get install nginx -y
rm -rf /etc/nginx/sites-enabled/default
rm -rf /etc/nginx/sites-available/default
cat <<EOT> /etc/nginx/sites-available/sonarqube
server{
listen 80;
server_name sonarqube.groophy.in;
access_log /var/log/nginx/sonar.access.log;
error_log /var/log/nginx/sonar.error.log;
proxy_buffers 16 64k;
proxy_buffer_size 128k;
location / {
proxy_pass http://127.0.0.1:9000;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;

proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
}
}
EOT
ln -s /etc/nginx/sites-available/sonarqube /etc/nginx/sites-enabled/sonarqube
systemctl enable nginx.service
#systemctl restart nginx.service
sudo ufw allow 80,9000,9001/tcp
echo "System reboot in 30 sec"
sleep 30
reboot

After complete we will do some post installation step.


ssh -i vprofile-ci-key.pem ec2-user@ublicipofNexus
sudo -i

Go to browser and copy your public ip of nexus port 8081

http://yournexuspublicipfromaws:8081/

Run

cat /opt/nexus/sonatype-work/nexus3/admin.password

Once completed you should be able to login :

Next you will be asked to change password and then you will be taking to the next screen, select disable ananoymous access, since we only want those with authentication to be able to download.

Once complete, we will go to settings, repositories and create a repository.

  1. Create a release repository example: vprofile-release
  2. Create a Dependency Repository — maven2 proxy and adding the url for maven dependency downloads.

3. Create maven hosted- snapshot… change version to snapshot.

4. Group repository to group all the repository together.

Next lets verify Sonarqube

Go to the public ip of sonarqube ->

Login

username- admin
password- admin

Once login, change your password.

Verify jenkin server ..ssh to your server ip and navigate to the location of your .pem file if you are not running the script from the location of where the pem file located.

ssh -i vprofile-ci-key.pem ubuntu@publicipsudo -i
systemctl status jenkins

Take Public ip and then navigate to ip:8080

Now let go to terminal and run

cat /var/lib/jenkins/secrets/initialAdminPassword

You should get the password and now you can proceed.

Click install suggested plugins

continue and then we will need to create username and password… and continue.

Let install Jenkins Plugin. Manage plugin and Plugin manager

Install the following

Let now proceed to setup a git code migration so we can setup github with our CI cd pipeline. We would need to be able to edit code etc so that it can trigger a build from jenkins etc.. So let start.

First go to your git bash and lets generate a key pair

ssh-keygen and hit enter

Once generated, you should see the location of public and private key. Run the following command against the public key location. Example:

cat /c/Users/kheml/.ssh/id_rsa.pub

Copy your key and go to github — settings → ssh and gpg key and add this key in there.

Test that everything is fine by going back to your gitbash and enter the following command:

ssh -T git@github.com

If you have a success, with your github account then you are ok.

Next step is to clone a project and import to our directory.

  1. Create a directory in your local drive
  2. Cd into that directory
git clone -b ci-jenkins https://github.com/devopshydclub/vprofile-project.git

Now you can rename the folder if you want to the name of the repository you created in github…then cd into that folder.

Run the command to get the URL of your remote orgin etc.

cat .git/configgit remote set-url origin
git remote set-url origin git@github.com:randi2160/vprociproject.git

Copy your url and run the following

git remote set-url origin git@github.com:{YOUR GITHUB}/vprociproject.gitgit branch -c maingit checkout main
git push --all origin

once all is completed you should be able to go to your github account and see the newly committed code.

Alright !!! we made it this far!! so let start creating our Pipeline. Pipeline needs some dependency.

Open up Jenkin → go to manage Jenkins → global tool configuration →

Add JDK version globally… JDK8 for our project.

Select Maven version.

Lets write our pipe line code. Open up the project and go to jenkinsfile.

We are going to write our code from scratch here.

pipeline {agent anytools {maven "MAVEN3"jdk "OracleJDK8"}environment {SNAP_REPO = 'vprofile-snapshot'NEXUS_USER = 'admin'NEXUS_PASS = 'admin123'RELEASE_REPO = 'vprofile-release'CENTRAL_REPO = 'vpro-maven-central'NEXUSIP = '3.84.213.250'NEXUSPORT = '8081'NEXUS_GRP_REPO = 'vpro-maven-group'NEXUS_LOGIN = 'nexuslogin'}stages {stage('Build'){steps {sh 'mvn -s settings.xml -DskipTests install'}}}}

--

--

Khemlall Mangal

I am a passionate coder, QA Engineer, and someone who enjoys the outdoors.