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:
- 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 - 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 containercontainer_port
: the port used by the containerhost_port
: the port on the host machinerollback_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.