Application deployment on Kubernetes cluster via Jenkins & Ansible.
--
Ansible is an opensource tool for software provisioning, configuration management, and application-deployment enabling infrastructure as code. There are many automation tools available which use the master-slave configuration, however Ansible uses the SSH connection for operations. Ansible playbooks are written on YAML which are easy to understand, and its OS agnostic behavior makes it interoperable. It has a capacity to handle hundreds of nodes with a single command.
Ansible playbook is a bunch of commands or tasks to be run on the host machine, it can be as simple as getting the hostname or installing any software. Inventory file keeps track of all the host machines on which Ansible playbook need to be run. You can create a group of hosts together or can have an individual host for the operation as shown below. Connection to the host machine is done via SSH key which is generated and copied on all the host machines to perform operation
Install and configure Ansible on Jenkins Server
#Step 1 : Install Ansible with the below commands based on the OS, use “ansible — version” command to verify the Ansible version
apt-get install ansible
yum install ansible
#Step 2 : Prepare SSH key and copy on the host machine. Use ssh-keygen tool to create SSH key if it doesn’t exist and copy it to the host machine with the below command.
ssh-copy-id hostuser@xxx.xxx.xx.xxx
#Step 3 : Create inventory file and validate the connectivity by pinging all the host machines. Edit the inventory file with below commands,
# sudo vim /etc/ansible/hosts
Create a host group and add the below details in the inventory file.
[group-one]
xx.xxx.xx.xxx
xx.xxx.xx.xxx
[group-two]
xx.xxx.xx.xxx
xx.xxx.xx.xxx
[group-three]
xx.xxx.xx.xxx
Ping a set of host from a group or all the host with below commands
# ansible -m ping group-one
OR
# ansible -m ping -all
Perfect, now when we have successfully completed the installation, let use the Jenkins server to deploy the application. We will be using a simple DevOps pipeline for the exploration where GitLab will hold the developers code, SonarQube will run the analysis with nexus storing the build artifacts and Ansible to deploy the artifacts on the Kubernetes cluster.
Follow below link to understand the Kubernetes cluster creation.
Jenkins configuration for Ansible integration
There are 2 different ways to integrate Ansible in Jenkins, we can install an Ansible plugin or mount the installation directories on to the Jenkins container.
Ansible Plugin : Login to the Jenkins server and install Ansible plugin from the plugin directory. After installation, add configuration to the Jenkins plugin as shown in below diagram.
Directory mounting : Edit the Jenkins docker compose file and mount the below directories.
/usr/lib/python2.7
/usr/bin/ansible
/usr/bin/ansible-playbook
/etc/ansible/hosts
/root/.ssh
Add deployment stage to the DevOps pipeline
Add a new stage to the DevOps pipeline to deploy the application to the Kubernetes cluster. Kubernetes master machine will act as one of the hosts in the inventory file and will store the deployment automation script. This script will be responsible to deploy the application to the Kubernetes worker nodes.
//stage to deploy application
stage('DEPLOY') {
steps {
script {
def tfHome = tool name: 'Ansible'
env.PATH = "${tfHome}:${env.PATH}"
sh 'ansible-playbook playbook.yaml'
}
}
}
Playbook will reside in the application repository and will be used to deploy the application. In the example above we have “playbook.yaml” which will be used by Ansible to invoke the deployment script on the Kubernetes master machine. Below is the sample example
---
- name: Deploy Application
hosts: group-one
remote_user: root
tasks:
- name: Terminate Old Application
command: bash -lc "cd /root/webapp/ && ./reset.sh"
register: reset
- debug: var=reset.stdout_lines- name: Deploy New Application
command: bash -lc "cd /root/webapp/ && ./deploy.sh"
register: deploy
- debug: var=deploy.stdout_lines
Output on successful execution
+ ansible-playbook playbook.yamlPLAY [Deploy Application] ****************************************************TASK [Gathering Facts] *********************************************************
ok: [xxx.xx.xxx.xx]TASK [Terminate Old Application] *******************************************************
changed: [xxx.xx.xxx.xx]TASK [debug] *******************************************************************
ok: [xxx.xx.xxx.xx] => {
"reset.stdout_lines": [
"pod \"webapp-87665d7fb-8jqqd\" deleted",
"service \"webapp\" deleted",
"deployment.apps \"webapp\" deleted",
]
}TASK [Deploy New Application] ******************************************************
changed: [xxx.xx.xxx.xx]TASK [debug] *******************************************************************
ok: [xxx.xx.xxx.xx] => {
"deploy.stdout_lines": [
"service/webapp created",
"deployment.apps/webapp created",
]
}PLAY RECAP *********************************************************************
xxx.xx.xxx.xx : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
That’s it!!
Happy Learning !!!