Deployment Automation Made Easy with Ansible and Jenkins Integration.

Deployment automation is crucial for delivering applications quickly and efficiently to production. With the Jenkins Ansible integration deployment can become a seamless process, reducing the risk of human error and increasing the speed of delivery. The combination of these two powerful tools provides a flexible and easy-to-use solution for automating deployment, making the process efficient and effortless for teams of all sizes.

What is Jenkins?

Jenkins is an open-source automation server that helps organizations build, test, and deploy applications efficiently. It provides a platform for continuous integration and continuous delivery, allowing teams to automate various parts of the software delivery pipeline. With its easy-to-use interface and powerful plugins, Jenkins helps organizations streamline their development and deployment processes, resulting in faster and more reliable software releases.”

What is ansible?

Ansible is a tool used to automate tasks such as application deployment, server updates and patching, and cloud provisioning. configuration management etc. Linux admins use Ansible to do the repetitive task that needs to run weekly, does daily ansible not require an agent to work or is no other security infrastructure needed
We have already discussed ansible and its various use cases Ansible

How we can automate our software deployment using Jenkins and ansible?

Assume our code is in GitHub and each time a commit to the main branch must build the docker image and run it as a container in the live server.
This is what means CI/CD setup. That means a developer only needs to work on his code and whenever he pushed or merges all the code to the main branch the code gets built automatically and deployed automatically to the live server.

For example, we have a sample nodejs application. We are going to dockerize this nodejs application and going set up CI/CD for this project using github>jenkins>ansible.

Prerequisites:

  1. Need a server with Jenkins, Ansible and docker installed. For reference visit our previous blogs.
    How to install and Configure Ansible on ubuntu 20.04
    How to Install and Configure Ansible on CentOS 7 in 5 Steps
    How to install docker in ubuntu 20.04
  2. Need to install git and docker plugins in the jenkins

Step 1:Write a docker file to build your nodejs -project

In the first step we need to create a dockerfile inorder to build our nodejs application.
We have already covered the basic of how to create a docker file in our previous article.
For reference Building Containers with Docker: Understanding the Dockerfile.

# Use an official node.js image as the base image
FROM node:14

# Set the working directory in the container
WORKDIR /app

# Copy the package.json file to the container
COPY package.json .

# Install the dependencies
RUN npm install

# Copy the rest of the application code to the container
COPY . .

# Specify the command to run the node.js application
CMD ["node", "server.js"]

This Dockerfile uses the official node.js image as the base image and sets the working directory to /app.
The package.json
file is copied to the container and the dependencies are installed using the npm install command. The rest of the application code is also copied to the container. The default command to run the container is specified using the CMD instruction, which is node server.js.

This is what my GitHub repo looks like after writing the docker file next thing I need to do is to create a Jenkins project for my application.

Step 2: Configure the Jenkins project.

  • Open Jenkins in your web browser and log in using the credentials.
  • Click on “New Item” on the left menu, enter a name for your project, and select “Freestyle project.”
  • Scroll down to the “Source Code Management” section and select “Git.”
  • Enter the repository URL for your GitHub project and provide your GitHub credentials .
  • Scroll down to the “Build” section and click on “Add build step.”
  • Select “Execute shell” from the options.
  • Enter the following command to run the Ansible playbook in the shell:
    ansible-playbook /var/lib/jenkins/workspace/project_name/playbook.yaml
  • Save the changes and click on “Build Now.”
  • Check the build output to see if the Ansible playbook has been executed successfully.

Here I am going to create a playbook with the name playbook.yaml In in order to build and deploy the node js application.
You need to add this playbook and docker file in your GitHub repo for Jenkins to build and deploy.

For automatic deployment of your code from GitHub on each commit you need to setup GitHub webhooks.

Setting up github webhooks.

  • In your Jenkins project, go to the “Configure” section.
  • Under the “Build Triggers” section, check the “GitHub hook trigger for GITScm polling” checkbox.
  • In your GitHub repository, go to the “Settings” section.
  • In the “Webhooks” section, click on the “Add webhook” button.
  • Enter the URL for your Jenkins instance in the “Payload URL” field. This should be in the following format: http://<jenkins_host>:<port>/github-webhook/.
  • Set the “Content type” to “application/json”.
  • Choose the events that you want to trigger the build. For example, “Just the push event”.

Step 3: Creating our ansible-playbook

Creating our ansible playbook for building the docker-image and deploying to the Jenkins server.
We have already covered the basic of ansible and how to create a sample playbook in our previous article for reference How to write Ansible playbooks.

Need to create the file with the same name defined in our Jenkins job and add to your GitHub repo.
Also, note that Jenkins users must have permission to run the playbook.

---
- name: play for nodejs deployment
  hosts: localhost
  vars:
    container_name: nodejs
    container_port: 3000
    host_port: 3000
    rollback_tag: rollback
  tasks:
    - name: Remove existing rollback image
      command: docker image rm {{container_name}}:rollback
      ignore_errors: yes
    - name: Stop and remove existing container if to avoid port conflict
      command: docker rm -f {{ container_name }}
      ignore_errors: yes
    - name: Tag current image for rollback for backup of image
      command: docker tag {{ container_name }}:latest {{ container_name }}:{{ rollback_tag }}
    - name: Building the docker container
      command: docker build -t  {{ container_name }}:latest /var/lib/jenkins/workspace/nodejs_sample/
    - name: Deploy the latest Docker image
      command: docker run -d --name {{ container_name }} -p {{ host_port }}:{{ container_port }}  {{ container_name }}:latest

The playbook performs the following actions:

  • Removes the existing rollback image, if any, with the docker image rm command.
  • Stops and removes any existing containers with the same name to avoid port conflicts, using the docker rm command.
  • Tags the latest image as a rollback image in case of failure in deployment using the docker tag command.
  • Builds a new Docker image using the docker build command and tags it as the latest version.
  • Deploys the latest Docker image using the docker run command maps the container port to the host port and starts the container in the background (detached mode)

The playbook is executed on the localhost and uses the become directive to run the tasks as the root user. The playbook uses the following variables:

  • container_name: the name of the Docker container
  • container_port: the port used by the container
  • host_port: the port on the host machine
  • rollback_tag: a tag used for tagging the current image as a rollback image.

Step 4: Configure Jenkins to execute the playbook

Initially, Jenkins might not have permission to docker group so you need to add a Jenkins user to the docker group.

sudo usermod -a -G docker jenkins

Now let’s try to do a commit from our git-repo it will automatically runs the Jenkins job and build the docker image and deploy it as a container.

From this Jenkins log we can understand that the code was successfully pulled from GitHub and deployed in the sever using ansible-playbook.

After the successful execution of the playbook, i checked my server if whether the deployment was successful or not.

From the below screenshot, you can see the nodejs container is successfully running on port 3000.

As our nodejs is running on port 3000 I tried accessing it from the browser and it was working fine as expected.

Summary: This is how we can use ansible-playbook to automate our deployments.

Leave a Reply

Your email address will not be published. Required fields are marked *