What is CI/CD?
Continuous integration (CI) is a software development practice in which developers merge the changes they have made to the main branch multiple times per day. When this happens, each merge triggers an automated code build and test sequence and if the build succeeds, then the code can be successfully merged and CD steps can be followed to proceed. Meanwhile, continuous delivery (CD) picks up where continuous integration ends and this process automates the delivery of applications to selected infrastructure environments.
Here are some popular CI/CD tools:
- AWS CodeCommit , CodeBuild , CodeDeploy and CodePipeline
and many more.
In this article we will be focusing on a specific tool called Jenkins.
As an extensible automation server, Jenkins can be used as a simple CI server or be transformed into the continuous delivery hub for any project. It is a continuous integration server, written in Java, for orchestrating a chain of actions to achieve the CI process in an automated fashion. Jenkins supports the complete development life cycle of the software from building and testing to documenting the software and deploying amongst other stages of the software development life cycle. Let's get started on this interesting tool. 🤖
First, let's get clear idea of what will be covered in this article:
- Setting up Jenkins
- Exploring the Jenkins UI
- GitLab integration to check builds
- Updating production servers when new code is approved.
Setting up Jenkins
Note: An important prerequisite for installing Jenkins is the you have Java installed on your system.
- I am going to proceed with the setup using Centos 8.x system. Use the following code to install Java and Jenkins:
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key sudo yum upgrade sudo yum install jenkins java-11-openjdk-devel sudo systemctl daemon-reload
- The next step is to start the series from Jenkins using the following code:
sudo systemctl start jenkins
- Check the status to ensure the at the services are active using the code given below:
sudo systemctl status jenkins
Not on Centos system, no worries! Get help here.
- The next step is to open localhost:8080 on your system. If you are using it for the first time, the following image will be your greeting page:
After unlocking Jenkins, the "Customise Jenkins" page will appear. You can install any number of useful plugins as part of your initial setup in this section.
Create the first admin user and restart Jenkins to proceed. You can go ahead and sign in now on:
Note: It is recommended that
localhost:8080is mapped to a domain name/IP or else the GitLab integration might not work properly when using
localhost. You can also optionally use a tunnelling software here.
Exploring the Jenkins UI
Here is what the dashboard will look like:
New Item - New Item is any job you want to build. Any fundamental task that one needs to develop or perform in Jenkins has to get started with the creation of a new item.
Manage Jenkins - It is place where we can manage the entire Jenkins infrastructure. This is where any required configurations can be made.
List of jobs - Here all the jobs are enlisted along with their status (🔵 -> Latest build was a success and 🔴 -> Latest Build was a failure). One can get the overview of the jobs and how they have been performing lately from this segment.
Build Executor Status - All the currently being executed jobs will be seen here in an active state. The others in queue will be visible above in the "Build Queue".
A look into some of the options on the "Manage Jenkins" page:
Configure System - Using this page, one can create general settings on Jenkins like configuring options for installed plugins, setting up global environment variables etc.
Global Tool Configuration - All the global tools that need to be used by the many jobs present in the Jenkins service can be configured in this section. For example: The installations, versions and other generic settings.
Manage Plugins - Plugins that can increase the functionality of Jenkins can be added, removed, enabled or disabled here.
Manage Credentials - Any credentials that Jenkins might require for its integration with other tools can be set up here.
GitLab integration to check builds
Step 1: Download the necessary plugins
- Go to Manage Jenkins -> Manage Plugins -> Available Plugins. See to it that you have the following plugins installed - Git, Git Client, GitLab API plugin, GitLab Branch Source Plugin and GitLab Plugin
Step 2: Create Personal Access Tokens on GitLab Account
- Personal Access tokens are like alternative set of credentials for any application that needs access to GitLab APIs. To create the same go to Edit Profile -> Access Tokens on your GitLab account and give the access token scopes of
read_user. One can grant scopes as per their requirement and need by doing this. To proceed, go ahead and copy the Personal Access token.
Step 3: Add the generated token to Jenkins
Here, we will add the generated token so that they can be used anywhere throughout Jenkins. Go to Manage Jenkins -> Manage Credentials -> (global) -> Add Credentials to achieve this. Refer to the image given below:
Fill the required fields:
- Select GitLab API token from the dropdown menu.
- Scope - This is as per your requirement and you can leave this as it is.
- API Token - Add the earlier copied API token.
- ID - I would suggest to add a meaningful ID/name to it.
Description - Add a description about the being created credentials.
Click on "OK" to complete this process.
Step 4: Create the integration
With this step we establish connection between GitLab and Jenkins. Go to Manage Jenkins -> Configure System to get started. Refer to the photo given below:
Fill in the required fields along with the token created previously by selecting it from the dropdown menu. Ensure to test the connection and if everything went right, you will derive at a successful output.
Step 5: Add ssh keys to GitLab and Jenkins
- This step is required so that Jenkins server can access repositories in the GitLab Account. Log
SSHinto the Jenkins server and run the code given below:
ssh-keygen -t rsa -m PEM -f blog-new.key
We are using this command instead of the general
ssh-keygenas this will run private and public key with an RSA algorithm and is also supported by all systems. Add public key to GitLab using the code given below:
Copy the output and go to Edit Profile -> SSH keys-> public key and set expiry to never. Add the private key to the Jenkins UI using the following code:
Copy output and go to Manage Jenkins -> Manage Credentials -> (global) -> Add Credentials. Here select the SSH Username along with the private key while adding the username as git. Refer to the image given below:
Step 6: Create the job -
Now this is the most important part for the entire flow to work. Go to New Item -> Freestyle project and you will arrive at a landing page which looks like this:
i) Here select the connection created in the previous step from the dropdown.
- Source Code Management
i) Here select Git and add enter the repository's URL (
git@xxxxx/xxxx.git) with the correct credential from dropdown.
ii) Leave "Branches to Build" as blank as we want all the branches to undergo the build/test process. This field can be edited if any particular branches are required to be built/tested.
- Build Triggers
Here all the conditions are specified that can trigger a build like as to what action on which branch can trigger the build for this job or any such condition One can edit the build as per the use case and requirement as shown below:
i) Build when a change is pushed to GitLab - This is selected so that events occurring on GitLab can trigger the build. (Copy the GitLab webhook URL and keep it)
ii) Push Events, Opened Merge Request Events - This is selected so that the events on specified branches can act as trigger.
iii) Filter branch by name - Selecting all branches on which of the above events will be set.
iv) Secret token - Generate this to be used along with the webhook URL.
- Build Environment
Here one can create any particular build environment that might be required for the build to successfully execute. For e.g., one can set the required Node environment here if is build set Node commands and one can also set a path to the configuration files here.
This is place where the
build takes place. In my case, I used Execute Shell and ran some build commands and test cases on the code that triggers the build.
- Post-build Actions
One can set any action that should take place after the completion of a build. For e.g., the easiest being adding the build status(success/failure) on GitLab merge requests or integrating Jenkins with Slack to send messages to a particular channel.
Step 6: Add webhook URL to GitLab -
Go to Repository -> Settings -> Webhooks.
Add the previously generated webhook URL and the secret token here.
Next, add Push Events and Merger Request Events as triggers.
- Now, you can either test it here itself by pressing the "Test" button or push a code to a branch in the repo to see which build can be triggered on Jenkins. If this is successful, you can see the following output:
- Click on the 🔵/🔴/⚪️ dot to see the console output:
- Assuming like in my case that Jenkins is hosted on a different server and there another production server exists that needs to updated when code is pushed to a master branch in GitLab, you can add the Jenkins server's public key to the production server's
~/.ssh/authorized_keysand go on to adding the Jenkins server's private key to the Jenkins UI. Here select the SSH Username along with the private key, add the username as non-root user on the production server and finally add the private key as depicted below:
- Go to Manage Jenkins -> Configure System -> SSH remote Hosts and add the necessary details and check your connection. An image of the result is given below:
~/.ssh/authorized_keyson production server should have the correct permissions.
- Similarly like the previous steps create a freestyle project but the only difference is nothing can be configured in the source code management or the webhooks on Jenkins. Create triggers on GitLab only for pushing the project to the master branch and add the following:
SSH site - The remote host added earlier. Command - The update script/commands.
- Now the production can be updated only by pushing the code to the master branch. 😊
To Sum It Up
Jenkins is an open source automation server which has many advantages. Some of them are given below:
- It is fairly simple to understand and implement in any project.
- Its open source and supported by many major platforms.
- Huge number of available plugins and if there is no plugin that suites a case one can go ahead and create custom plugins.
- If one is using Sonarqube(Code Quality Inspection tool), Jenkins is one of the most available CIs.
Hope you found this article interesting and would go ahead and explore this very popular tool. Happy DevOps!! 😁😁