In this tutorial, our goal is to perform the follow task:
- ssh to the remote server
- call git pull update for the changes
- call maven package to compile war file
- stop tomcat
- remove previous version java apps
- deploy the newly compile war file to tomcat webapps
- start tomcat
Assume we have the follow servers that need to execute all the task whenever there is the new commit code.
IP Address | Short Hostname | Username | Password |
---|---|---|---|
123.123.123.121 | ABC121 | root | password123 |
123.123.123.122 | ABC122 | root | password123 |
123.123.123.123 | ABC123 | root | password123 |
123.123.123.124 | ABC124 | root | password123 |
123.123.123.125 | ABC125 | root | password123 |
Create a new project folder
Create a new project folder named playbook2. By end of this tutorial, you should have the following files listed.
- [path]/playbook2/ansible.cfg
- [path]/playbook2/inventory
- [path]/playbook2/javadev.yml
- [path]/playbook2/gitcredential/.git-credential
Create a inventory file
This inventory file keep our servers information, [abc] is group name
[abc] ABC121 ansible_ssh_host=123.123.123.121 ansible_ssh_port=22 ansible_ssh_user=root ABC122 ansible_ssh_host=123.123.123.122 ansible_ssh_port=22 ansible_ssh_user=root ABC123 ansible_ssh_host=123.123.123.123 ansible_ssh_port=22 ansible_ssh_user=root ABC124 ansible_ssh_host=123.123.123.124 ansible_ssh_port=22 ansible_ssh_user=root ABC125 ansible_ssh_host=123.123.123.125 ansible_ssh_port=22 ansible_ssh_user=root
Create a ansible.cfg file
This ansible.cfg file has few default argument. like hostfile value inventory is pointing to the inventory file we’ve just created.
[defaults] hostfile = inventory ansible_connection: ssh ask_pass: True [ssh_connection] ssh_args = ""
Test Run in Terminal
Our first goal is to ping each server so that we can continue develop the task to fulfill the above requirement. If you encounter failure add -vvvv arguments for error details. If everything run fine, you should have similar result.
(ansible_env) MacBook-Air:playbook2 mingch$ ansible all -i inventory -m SSH password: ABC121 | SUCCESS => { "changed": false, "ping": "pong" } ABC122 | SUCCESS => { "changed": false, "ping": "pong" } ABC123 | SUCCESS => { "changed": false, "ping": "pong" } ABC124 | SUCCESS => { "changed": false, "ping": "pong" } ABC125 | SUCCESS => { "changed": false, "ping": "pong" }
Tasks Creation
Now it’s time to create task by task. The following is piece of code for each task describe what you need to accomplish the task given. The most tricky part for me is the git pull request, because it required to enter username and password. While if directly execute playbook will causing terminal stuck to wait for user input credential without acknowlegement. Details part will be explain in shortly.
Create task stop tomcat
At first, we need to stop the tomcat.
tasks: - name: tomcat stop service: name=tomcat state=stopped
Create task start tomcat
When everything is deployed, we need to start the tomcat.
tasks: - name: tomcat start service: name=tomcat state=started
Delete war file in tomcat webapps
During deployment, deleted the old war file.
tasks: - name: delete war file in tomcat webapps file: path=/usr/share/tomcat/webapps/myproject.war state=absent
Delete war directories in tomcat webapps
During deployment, deleted the old web project files in recursively.
tasks: - name: delete war file in tomcat webapps file: path=/usr/share/tomcat/webapps/myproject state=absent
Copy file in tomcat webapps
Copy the war file to the tomcat webapps folder. You can also set variable with arguments vars.
vars: remote_warfile: /root/workspace/myproject/target/myproject.war remote_webapps: /usr/share/tomcat/webapps/ tasks: - name: copy war file command: cp {{ remote_warfile }} {{ remote_webapps }}
Maven compile code
Maven run clean and package command to build the war archive.
tasks: - name: maven clean package command: mvn -f /root/workspace/myproject/pom.xml clean package
Prerequisition setup
The remote server has git installed and used git pull that required you prompt input username and password. There are many way to store credential in locally by third party help, such as using private key, KDE wallet, netrc and etc. In my case, that a bit different. First it require you execute with helper store. Execute the following command in your remote server projec checkout folder.
git config credential.helper store
Or you can directly execute this command in any place with –git-dir=/your_project_path/.git
git --git-dir=/root/workspace/myproject/.git config credential.helper store
After this command is executed, you can either manually create a file in the location ~/.git-credentials immediate to test pull request without prompt for username and password.
remote-server# echo "https://myusername:mypassword@gitlab.com" > .git-credentials
OR you can run pull request that will prompt for enter username and password, afterward it will no longer required. And username and password will store in plain text in the following location if you did not provide option arguments here is the location.
more ~/.git-credentials https://myusername:mypassword@gitlab.com
Delete .git-credentials
Create a .git-credentials in your project folder. [path]/playbook2/gitcredential/ and delete the remote server .git-credentials
(ansible_env) MacBook-Air:playbook2 mingch$ echo "https://myusername:mypassword@gitlab.com" > gitcredential/.git-credentials
Create Task for git pull update
tasks: - name: check out the repository on the host git: repo=https://gitlab.com/loongest/myproject.git dest=/root/workspace/myproject/ accept_hostkey=yes
Complete playbook yml file example
This is the final playbook, at first I’ve set a of variables, then task and handler. Handler is just like a task but it only run when get trigger by notify syntax.
- name: Git pull maven compile tomcat deploy hosts: tutorial become: yes become_method: sudo vars: remote_warfile: /root/workspace/myproject/target/myproject.war remote_webapps: /usr/share/tomcat/webapps/ local_git_credential: gitcredential/.git-credentials remote_git_credential: ~/.git-credentials tasks: - name: tomcat stop service: name=tomcat state=stopped - name: copy git .git-credentials copy: src={{ local_git_credential }} dest={{ remote_git_credential }} - name: check out the repository on the host git: repo=https://gitlab.com/loongest/myproject.git dest=/root/workspace/myproject/ accept_hostkey=yes - name: maven clean package command: mvn -f /root/workspace/myproject/pom.xml clean package - name: delete war directories in tomcat webapps file: path=/usr/share/tomcat/webapps/myproject.war state=absent - name: delete war file in tomcat webapps file: path=/usr/share/tomcat/webapps/myproject state=absent - name: delete git credential file file: path={{ remote_git_credential }} state=absent - name: copy war file command: cp {{remote_warfile}} {{remote_webapps}} notify: start tomcat handlers: - name: start tomcat service: name=tomcat state=started
Pingback:Ansible tutorial ‹ CodeOmitted
Thanks dude
I am seeking for this code in lot websites those are not clear finally I saw this
Its working perfectly thanks again
Thanks
I have configured my Ansible control and slave node on Amazon EC2
Operating System:https://www.redhat.com/Red Hat Enterprise Linux 8.0 (Ootpa)
Issue – tomcat is not getting started on slave node. So i had to do it manually and it is working fine.
Please help.
playbook to install java
[root@ip-10-0-0-82 playbooks]# vim installjava.yml
—
– hosts: all
tasks:
– name: copy files from src to dest
copy:
src: /home/ec2-user/jdk-8u231-linux-x64.tar.gz
dest: /opt
– name: Unarchive a file that is already on the remote machine
unarchive:
src: /opt/jdk-8u231-linux-x64.tar.gz
dest: /opt
remote_src: yes
– name: Defining JAVA_HOME
lineinfile:
dest: /etc/profile
state: present
line: ‘{{ item }}’
with_items:
– ‘export JAVA_HOME=/opt/jdk1.8.0_231’
– ‘export PATH=$JAVA_HOME/bin:$PATH’
– name: sourcing profile
shell: source /etc/profile
———————————————————————————————————–
playbook to deploy .war file
[root@ip-10-0-0-82 playbooks]# vim deploysjavacode.yml
—
– hosts: DB
tasks:
– name: Download MVN
get_url: url=https://www-eu.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz dest=/opt/
– name: Extract archive
command: chdir=/usr/share /bin/tar xvf /opt/apache-maven-3.6.3-bin.tar.gz -C /opt/
– name: Defining MVN_HOME
lineinfile:
dest: /etc/profile
state: present
line: ‘{{ item }}’
with_items:
– ‘export MVN_HOME=apache-maven-3.6.3’
– ‘export PATH=$MVN_HOME/bin:$PATH’
– name: update sourece
shell: source /etc/profile
– name: clone code
shell: cd /tmp; /usr/bin/git clone https://github.com/shekharshamra/jenkin.git; cd /tmp/jenkin; mvn clean install
– name: Download apache tomcat
get_url: url=http://mirrors.estointernet.in/apache/tomcat/tomcat-8/v8.5.50/bin/apache-tomcat-8.5.50.tar.gz dest=/opt/
– name: Extract archive
command: chdir=/usr/share /bin/tar xvf /opt/apache-tomcat-8.5.50.tar.gz -C /opt/
– name: deploy code
shell: cd /tmp/jenkin/in28minutes-web-servlet-jsp/target ;cp in28minutes.war /opt/apache-tomcat-8.5.50/webapps/
– name: Recursively change ownership of a directory
file:
path: /opt/apache-tomcat-8.5.50
state: directory
recurse: yes
owner: tomcat
group:
handlers:
– name: Restart tomcat
service: name=tomcat state=started
—————————————————————————————————————————————–
[root@ip-10-0-0-82 playbooks]# ansible-playbook deploysjavacode.yml
PLAY [DB] *************************************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************************
ok: [10.0.0.129]
TASK [Download MVN] ***************************************************************************************************************************
ok: [10.0.0.129]
TASK [Extract archive] ************************************************************************************************************************
[WARNING]: Consider using the unarchive module rather than running ‘tar’. If you need to use command because unarchive is insufficient you
can add ‘warn: false’ to this command task or set ‘command_warnings=False’ in ansible.cfg to get rid of this message.
changed: [10.0.0.129]
TASK [Defining MVN_HOME] **********************************************************************************************************************
ok: [10.0.0.129] => (item=export MVN_HOME=apache-maven-3.6.3)
ok: [10.0.0.129] => (item=export PATH=$MVN_HOME/bin:$PATH)
TASK [update sourece] *************************************************************************************************************************
changed: [10.0.0.129]
TASK [clone code] *****************************************************************************************************************************
changed: [10.0.0.129]
TASK [Download apache tomcat] *****************************************************************************************************************
changed: [10.0.0.129]
TASK [Extract archive] ************************************************************************************************************************
changed: [10.0.0.129]
TASK [deploy code] ****************************************************************************************************************************
changed: [10.0.0.129]
TASK [Recursively change ownership of a directory] ********************************************************************************************
changed: [10.0.0.129]
PLAY RECAP ************************************************************************************************************************************
10.0.0.129 : ok=10 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0