Overview
We would be deploying Jenkins on AWS, integrate it with Artifactory and SonarQube.
We're using SonarQube to generate reports on coding standards, unit tests, code coverage, code complexity, bugs, and security recommendations. And JFrogs's Artifactory for artifacts strorage
A. AWS Console Deployment: Jenkins, Sonarqube and Artifactory
1. Create a VPC
We'll be using a VPC to host and manage securely our instances that will be running Jenkins, Sonarqube and Artifactory.
- Go to VPC
- Create VPC
- Select VPC and more
- Input a name for your VPC (e.g. TestVPC)
- IPv4 CIDR: 10.0.0.0/16
- No IPv6
- Number of public subnets: 1
- Number of private subnets: 1
- Click "Customize Subnets CIDR blocks" "
- Under Public subnet: 10.0.1.0/24
- Under Private subnet: 10.0.2.0/24
- Click "Create VPC"
It should look something like this:
Selecting VPC and more automatically creates a subnet, Internet gateway and route tables
2. Create NAT Gateway
- VPC Dashboard → NAT Gateways → Create
- Select the subnet created while creating the VPC (you should see it with a similar name as your VPC)
- Connectivity type: public
- Allocate new EIP
- Create NAT Gateway
3. Edit Route Table
- Select route table associated with private subnet
- Edit routes
- Add route: > - Destination: 0.0.0.0/0 > - Target: Select your NAT Gateway > - Save changes
It should look something like this:
Now we move to creating EC2 Instances...
EC2 Instances Setup
1. Jenkins Instance (Public Subnet)
- EC2 Dashboard → Launch Instance
- Name: test-jenkins
- AMI: Ubuntu 22.04 LTS
- Instance type: t2.micro
- Key pair: Create/select existing
- Click "Edit" (under network setting)
- VPC: TestVPC
- Subnet: Public subnet created earlier
- Auto-assign public IP: Enable
- Click "Create security group"
- Name: jenkins-sg
- Inbound rules:
- SSH (22): Your IP
- Custom TCP (8080): Your IP or Anywhere (0.0.0.0/0)
It should look something like this:
2. Artifactory Instance (Private Subnet)
- EC2 Dashboard → Launch Instance
- Name: Artifactory
- AMI: Ubuntu 22.04 LTS
- Instance type: t2.medium
- Key pair: Same as that used for Jenkins instance
- Click "Edit" (under network setting)
- VPC: TestVPC
- Subnet: Private subnet created earlier
- Auto-assign public IP: Disable
- Click "Create security group"
- Name: artifactory-sg
- Inbound rules:
- SSH (22): jenkins-SG
- Custom TCP (8081-8082): jenkins-SG
It should look something like this:
3. Sonarqube Instance (Private Subnet)
- EC2 Dashboard → Launch Instance
- Name: Sonarqube
- AMI: Ubuntu 22.04 LTS
- Instance type: t2.medium
- Key pair: Same as that used for Jenkins instance
- Click "Edit" (under network setting)
- VPC: TestVPC
- Subnet: Private subnet created earlier
- Auto-assign public IP: Disable
- Click "Create security group"
- Name: sonarqube-sg
- Inbound rules:
- SSH (22): bastion-SG
- Custom TCP (9000): jenkins-SG
It should look something like this:
Next, we'll be creating another Instance for Bastion Host.
A bastion host is a server used to manage access to an internal or private network from an external network.
In our case, we'll be using it to ssh into the private subnet for managing Artifactory and Sonarqube.
4. Bastion Host (Public Subnet)
- EC2 Dashboard → Launch Instance
- Name: Bastion
- AMI: Ubuntu 22.04 LTS
- Instance type: t2.micro
- Network: Public subnet
- Security Group:
- Allow SSH from your IP
- Allow outbound to Artifactory SG
It should look something like this:
B. Instalation of Jenkins, Artifactory and Sonarqube
Now we're done setting up and configuring our instances. Next, we'll be installing our tools: Jenkins, Artifactory and Sonarqube
1. Jenkins Installation
To install Jenkins, we'll be using docker. Specifically, we'll be spinning up a jenkins container using a docker-compose.yaml file.
- SSH to jenkins using
ssh -i <identity-file> ubuntu@<jenkins-public-ip>
Install docker
sudo apt-get update sudo apt-get install docker.io -y
- Add docker to usergroup with this command:
sudo usermod -aG docker $USER
Logout and login again
Test that docker is installed properly:
docker run hello-world
something like this should show:
- Next, we install docker compose
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} mkdir -p $DOCKER_CONFIG/cli-plugins curl -SL https://github.com/docker/compose/releases/download/v2.32.0/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
- Confirm docker compose is installed
docker compose version
It should bring an output like this:
Create a file with the name
docker-compose.yaml
.Paste this into the file:
services: jenkins: image: jenkins/jenkins:lts container_name: jenkins privileged: true user: root ports: - "8080:8080" - "50000:50000" volumes: - jenkins_home:/var/jenkins_home - /var/run/docker.sock:/var/run/docker.sock command: | sh -c " apt-get update && \ apt-get install -y sudo && \ chown -R 1000:1000 /var/jenkins_home && \ apt-get -y install docker.io && \ groupadd -f docker && \ usermod -aG docker jenkins && \ echo 'jenkins ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers && \ chown jenkins:jenkins /var/run/docker.sock && \ chmod 666 /var/run/docker.sock && \ su jenkins -c /usr/local/bin/jenkins.sh" volumes: jenkins_home:
- Run
docker compose up -d
This installs docker and spins up a jenkins container as well. In addition, it installs sudo which is needed to run some commands in our jenkins pipeline.
Access Jenkins UI by opening in your browser:
http://<jenkins-public-ip>:8080
Follow the prompt and Install selected plugins
2. Sonarqube Installation
Like we did for jenkins, we'll also be installing Sonarqube using docker
- SSH to sonarqube from Bastion
# SSH first to bastion ssh -i <identity-file> ubuntu@<bastionpublic-ip> # SSH to Sonarqube ssh -i <identity-file> ubuntu@<sonarqube-private-ip>
- Install docker
Go to previous install docker step
Create a file with the name
docker-compose.yaml
.Paste this into the file:
services: sonarqube: image: sonarqube:lts container_name: sonarqube ports: - "9000:9000" volumes: - sonarqube_data:/opt/sonarqube/data - sonarqube_extensions:/opt/sonarqube/extensions - sonarqube_logs:/opt/sonarqube/logs restart: always volumes: sonarqube_data: sonarqube_extensions: sonarqube_logs:
- Run
docker compose up -d
Run
docker ps
to ensure Sonarqube is runningAccess Sonarqube UI by opening in your browser:
Because we setup sonarqube in a private subnet, it doesn't have any public ip. And so we'll be accessing the UI using SSH tunnelling or SSH port forwarding from the Bastion host.
- From your local machine, run this: (We are forwarding traffic from our local machone's port 9000 to Sonarqube's port 9000 in the private subnet, through Bastion.)
# From your local machine, run ssh -L 9000:<sonarqube-private-ip>:9000 ubuntu@<bastion-public-ip>
On your local machine browser enter
http://localhost:8082
.It should open something like this:
P.s. Because my local machine's port 9000 is already being used, that is why i'm using port 9023.
Default login:
- username: admin
- password: admin
3. Artifactory Installation
Like we did for both Jenkins and Sonarqube, we'll be installing Artifactory using docker
- SSH to Artifactory from Bastion
# From your local machine, SSH first to bastion ssh -i <identity-file> ubuntu@<bastionpublic-ip> # SSH to Artifactory ssh -i <identity-file> ubuntu@<artifactory-private-ip>
- Install docker
Go to previous install docker step
Create a file with the name
docker-compose.yaml
.Paste this into the file:
services: artifactory-service: image: docker.bintray.io/jfrog/artifactory-oss:7.49.6 container_name: artifactory restart: always networks: - ci_net ports: - 8081:8081 - 8082:8082 volumes: - artifactory:/var/opt/jfrog/artifactory volumes: artifactory: networks: ci_net:
- Run
docker compose up -d
Run
docker ps
to ensure Artifactory is runningAccess Artifactory UI by opening in your browser:
Just like for Sonarqube, we'll be accessing the Artifactory UI using SSH port forwarding from the Bastion host.
- Run this:
# From your local machine ssh -L 8082:<artifactory-private-ip>:8082 ubuntu@<bastion-public-ip> # 8082 is Artifactory's UI port
On your local machine browser enter
http://localhost:8082
.It should open something like this:
Default login:
- username: admin
- password: password
Setting up Jenkins
Now we're going to install some plugins needed to configure Artifactory and Sonarqube in our Jenkins pipeline
First we'll be installing he Artifactory plugin
Go to Manage Jenkins > Plugins > Available Plugins, and search for
artifactory
Select and tick the first one, then click install:
- Search also for
sonarqube
. Select and tick the first one, then click install:
Next, let's configure Artifactory and Sonarqube on our jenkins server
Configure Sonarqube
Click Manage jenkins > System Configurations
Scroll to
Sonarqube servers
Click
Add Sonarqube
Name: Sonarqube (It has to tally with what you set as value for your env variable in your pipeline)
Server URL: http://:9000
Server authntication token. Let's create one
In your sonarqube ui, go to My account (top right)> Security> Generate token.
Type: User token
Expiration: no expiration
Click Generate
Make sure to copy the generated token
- Add Server authentication token
Kind: Secret text
Scope: Global
Secret: the generated token you copied
ID: sonarqube-token (or whichever name of choice)
Click Add
Select sonarqube token
Click Save
It should look like this:
Configure Artifactory
Click Manage jenkins > System Configurations
Scroll to
JFrog
Click
Add JFrog Platform Instance
Instance ID: artifactory1 (It has to tally with same value of your env variable in your pipeline)
JFrog Platform URL: http://:8082
Default Deployer Creentials.
Username: admin
Password: (new password you set when JFrog prompted you to change default password)
Click Test Connection
It should show something like this:
- Click Save
Configure Maven
Click Add maven
Name: enter one of your choice
Tick Install automatically
Version: Select a recent stable one (3.9.9 in this case)
Click Save
It should look like this:
Create Repository in Artifactory
We need to create a local repository in Artifactory where we would upload artifacts to. Here's a step-by-step on how to do it:
- Click Add Repositories (top right) > Local Repository
- Select Maven as package type
Repository key: test001 (same name to be used in Upload artifactory stage when uploading artifact)
Click Create Local Repository
And we're all setup!
Now we can go ahead to create a pipeline script, sourcing from a Java application created with springboot.
If you would want to see a sample Jenkins pipeline, i've actually written an article on the steps i took to create the pipeline script. Check here
Final Results:
And so we've created and ran a successful build:
When we check our Sonarqube, we see a newly created project from our build. We can also see reports, which we can expand on and read indepthly:
And in the Artifactory ui dashboard, we can see the newly created artifact under test001:
Conclusion
By integrating Artifactory and SonarQube into Jenkins, it helps streamline your Continuous Integration (CI) and Continuous Delivery (CD) pipeline, improves the quality of your code, and increases productivity.
Key Benefits
- Continuous Delivery: By linking Jenkins, Artifactory, and your deployment pipelines, you can automate the entire process from building to testing, and finally deploying the artifacts. Artifactory stores these artifacts until they are deployed to different environments.
- Integration with docker: Jenkins can build Docker images and push them to Artifactory. Artifactory supports Docker image repositories, so you can manage and store Docker images as part of your CI/CD pipeline.
- Early Detection of Code Issues: By running static analysis in the pipeline, SonarQube can quickly detect problems in the code base before they become bigger issues. This allows developers to fix problems early, saving time and reducing the cost of fixing issues later in the cycle.
Happy Building and Collaborating!
Top comments (0)