In this blog, we will explore the CI/CD process using Jenkins and Ansible. We will deploy the sample java application using Ansible on the tomcat servers. At last,this process will help us in achieving continuous integration and continuous deployment for your application.
If you want to see the video for this article, click here
Prerequisite:
- Two AWS EC2 instance ( one is Jenkins Server and another is tomcat server)
- Follow Jenkins Installation article if not already installed
- Integration between Jenkins and Ansible
- Make sure ssh connection is already setup between for jenkins user between two AWS EC2 Instances.
Agenda:
- Create a sample application in java
- Compile the project using maven
- Package the project in war file
- Create a role in Ansible to install java and tomcat
- Deploy the war file on tomcat server using ansible playbook
- Push the code in the github
- Create a pipeline job in Jenkins and trigger the build
Sample Application in Java
Firstly, create a sample registration and login page in jsp.
Compile and package the project using Maven
Created a pom.xml file to compile and package the project in war file. Clone the git repo and run the mvn command, this will generate a war file under target folder
git clone https://github.com/devops4solutions/CI-usingAnsible.git
mvn package
Now we have generated the war file and we can deploy it on our tomcat server. Previously, we used to install tomcat and java manually on the server and then copy the war file under webapps folder and restart the service.
Now, we will write the ansible roles to do all the tasks and configure it to run inside a Jenkins job
Ansible Playbook
In the git repo, we have created first ansible.cfg
file with the below entries
[defaults]
host_key_checking = False
This is required to bypass the hostkey checking while making a ssh connection with the tomcat servers. If you will not use this file, then when you run your playbook using jenkins it will fail with the error Host key verification is falied
Now we will create main.yml
file which will call our roles to install tomcat and java
- hosts: all
become: true
become_user: root
gather_facts: false
tasks:
- include_role:
name: tomcat
I have following folder structure to manage ansible playbook for inventories and the variables as shown below
Role to install java, configure tomcat and deploy the war file on the tomcat server
- name: Install Java 1.7 yum: name=java-1.7.0-openjdk state=present - name: add group "tomcat" group: name={{tomcat_group}} - name: add user "tomcat" user: name={{tomcat_user}} group={{tomcat_group}} home=/usr/share/tomcat createhome=no become: True become_method: sudo - name: Download Tomcat get_url: url=http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.61/bin/apache-tomcat-7.0.61.tar.gz dest=/opt/apache-tomcat-7.0.61.tar.gz - name: Extract archive command: chdir=/usr/share /bin/tar xvf /opt/apache-tomcat-7.0.61.tar.gz -C /opt/ creates=/opt/apache-tomcat-7.0.61 - name: Symlink install directory file: src=/opt/apache-tomcat-7.0.61 path=/usr/share/tomcat state=link - name: Change ownership of Tomcat installation file: path=/usr/share/tomcat/ owner=tomcat group=tomcat state=directory recurse=yes - name: Configure Tomcat server template: src=server.xml dest=/usr/share/tomcat/conf/ - name: Create sample directory file: path: "/opt/apache-tomcat-7.0.61/webapps/samples" state: directory mode: 0777 become: true - name: copy war file copy: src=./target/LoginWebApp-1.war dest=/opt/apache-tomcat-7.0.61/webapps/ notify: restart tomcat - name: Install Tomcat init script copy: src=tomcat-initscript.sh dest=/etc/init.d/tomcat mode=0755 - name: Start Tomcat service: name=tomcat state=started enabled=yes - name: wait for tomcat to start wait_for: port={{http_port}}
Also,you can check more articles on how to manage ansible playbook/inventories/multiple environments
Jenkins Pipeline
Now we will write Jenkinsfile to run all the tasks together as mentioned above
- Configure agent
- Configure tool maven and ansible which you have configured in your Jenkins. Name should match as per your jenkins configuration
- Checkout the code, its not required if you directly take the Jenkinsfile from SCM.
- Set the environment path
- Execute the
mvn package
- Lastly, run the ansible playbook
pipeline { agent any tools { maven "Maven" } stages { stage('checkout') { steps { git branch: 'master', url: 'https://github.com/devops4solutions/CI-example.git' } } stage('Tools Init') { steps { script { echo "PATH = ${PATH}" echo "M2_HOME = ${M2_HOME}" def tfHome = tool name: 'Ansible' env.PATH = "${tfHome}:${env.PATH}" sh 'ansible --version' } } } stage('Execute Maven') { steps { sh 'mvn package' } } stage('Ansible Deploy') { steps { sh "ansible-playbook main.yml -i inventories/dev/hosts -- user jenkins --key-file ~/.ssh/id_rsa" } } } }
Configure a Jenkins Pipeline project
- Create a pipeline job in Jenkins
- Configure gitrepo. I have used ssh url because my jenkins is already integrated with github
Click on Save and trigger the pipeline
Now, you can browse your application by using the url http://yourip:8080/LoginWebApp-1/ and you will see the login page as shown below:
Congratulations,you have successfully setup the CI/CD process using Jenkins and Ansible. You can also integrate your job with sonarqube to check the code quality and code coverage.