![]() | |
http://www.deviantart.com/art/The-Black-Tomcat-159041026 |
- Tomcat depends on Java ... I'm going to assume Java is present and in a known location (the same for all the target hosts).
- The target hosts have access to the internet (this allows them to download the Tomcat archive).
- The target hosts use upstart.
A first new concept is that of groups. Those are defined in the Ansible hosts file.
[ansible@ansibleworkstation ~]$ vi /etc/ansible/hosts
ansibleworkstation
[tomcat-servers]
athena
Quite simple, a group ... groups together hosts of the same kind. So here we have a group tomcat-servers. Note that a host can be in multiple groups.
Similar to variables for a host, there are variables for a group.
[ansible@ansibleworkstation ~]$ mkdir /etc/ansible/group_vars
[ansible@ansibleworkstation ~]$ mkdir /etc/ansible/group_vars/tomcat-servers
[ansible@ansibleworkstation ~]$ vi /etc/ansible/group_vars/tomcat-servers/vars
tomcat7_http_port: 8080
tomcat7_version: 7.0.73
tomcat7_admin_username: "{{ vault_tomcat7_admin_username }}"
tomcat7_admin_password: "{{ vault_tomcat7_admin_password }}"
[ansible@ansibleworkstation ~]$ vi /etc/ansible/group_vars/tomcat-servers/vault
vault_tomcat7_admin_username: admin
vault_tomcat7_admin_password: adminsecret
[ansible@ansibleworkstation ~]$ ansible-vault encrypt /etc/ansible/group_vars/tomcat-servers/vault
Remember that we don't want multiple vault passwords, so use the same one you used for the host variables. I think it's quite clear what the variables mean, so lets move straight on to the playbook.
[ansible@ansibleworkstation ~]$ vi /etc/ansible/playbooks/tomcat7.yml
---
- hosts: tomcat-servers
remote_user: root
become: yes
become_method: sudo
roles:
- tomcat7
No rocket science there either, this playbook will execute the role tomcat7 on the hosts in the tomcat-servers group. Before we can run the playbook however we have to define the role.
[ansible@ansibleworkstation ~]$ mkdir /etc/ansible/roles
[ansible@ansibleworkstation ~]$ mkdir /etc/ansible/roles/tomcat7
[ansible@ansibleworkstation ~]$ mkdir /etc/ansible/roles/tomcat7/tasks
[ansible@ansibleworkstation ~]$ vi /etc/ansible/roles/tomcat7/tasks/main.yml
---
# http://docs.ansible.com/ansible/group_module.html
- name: add group "tomcat"
group:
name: tomcat
# http://docs.ansible.com/ansible/user_module.html
- name: add user "tomcat"
user:
name: tomcat
group: tomcat
home: /usr/share/tomcat
createhome: no
# http://docs.ansible.com/ansible/unarchive_module.html
- name: extract archive
unarchive:
remote_src: yes
src: "http://archive.apache.org/dist/tomcat/tomcat-7/v{{ tomcat7_version }}/bin/apache-tomcat-{{ tomcat7_version }}.tar.gz"
dest: /opt
creates: "/opt/apache-tomcat-{{ tomcat7_version }}"
# http://docs.ansible.com/ansible/file_module.html
- name: symlink installation directory
file:
src: "/opt/apache-tomcat-{{ tomcat7_version }}"
path: /usr/share/tomcat
owner: tomcat
group: tomcat
state: link
# http://docs.ansible.com/ansible/file_module.html
- name: change ownership of the installation
file:
path: "/opt/apache-tomcat-{{ tomcat7_version }}"
owner: tomcat
group: tomcat
recurse: yes
state: directory
# http://docs.ansible.com/ansible/template_module.html
- name: configure server
template:
src: server.xml
dest: "/opt/apache-tomcat-{{ tomcat7_version }}/conf"
mode: 0600
owner: tomcat
group: tomcat
# http://docs.ansible.com/ansible/template_module.html
- name: configure users
template:
src: tomcat-users.xml
dest: "/opt/apache-tomcat-{{ tomcat7_version }}/conf"
mode: 0600
owner: tomcat
group: tomcat
# http://docs.ansible.com/ansible/template_module.html
- name: upstart script
template:
src: tomcat7.conf
dest: "/etc/init"
mode: 0644
owner: root
group: root
when: ansible_service_mgr == "upstart"
# http://docs.ansible.com/ansible/service_module.html
- name: enable and start service
service:
name: tomcat7
state: started
enabled: yes
A role has tasks. Note that added a reference to the documentation for each type of task mentioned. What are the tasks ?
- Create a group tomcat
- Create a user tomcat
- Download and extract the Tomcat archive (which one depends on the version variable) into /opt
- Create a symbolic link /usr/share/tomcat to the installation.
- Set the ownership of the installation.
- Update server.xml based on the variables and a template.
- Update tomcat-users.xml based on the variables and a template.
- Install the upstart script.
- Start Tomcat.
Three templates are used in the tasks (server.xml, tomcat-users.xml, tomcat7.conf). Templates are files that are modified based on available variables and facts. Note that I only show the relevant bits of the files below.
[ansible@ansibleworkstation ~]$ mkdir /etc/ansible/roles/tomcat7/templates
[ansible@ansibleworkstation ~]$ vi /etc/ansible/roles/tomcat7/templates/tomcat-users.xml
<?xml version='1.0' encoding='utf-8'?>
...
<!-- {{ ansible_managed }} -->
...
<tomcat-users>
<role rolename="manager-gui"/>
<user username="{{ tomcat7_admin_username }}" password="{{ tomcat7_admin_password }}" roles="manager-gui" />
</tomcat-users>
[ansible@ansibleworkstation ~]$ vi /etc/ansible/roles/tomcat7/templates/server.xml
<?xml version='1.0' encoding='utf-8'?>
<!-- {{ ansible_managed }} -->
...
<Service name="Catalina">
...
<Connector port="{{ tomcat7_http_port }}" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
...
[ansible@ansibleworkstation ~]$ vi /etc/ansible/roles/tomcat7/templates/tomcat7.conf
# {{ ansible_managed }}
description "Tomcat {{ tomcat7_version }} Server"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
respawn limit 10 5
setuid tomcat
setgid tomcat
env JAVA_HOME=/usr/lib/jvm/java-8-oracle/jre
env CATALINA_HOME=/opt/apache-tomcat-{{ tomcat7_version }}
env JAVA_OPTS="-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom"
env CATALINA_OPTS="-Xms512M -Xmx1024M -server -XX:+UseParallelGC"
exec $CATALINA_HOME/bin/catalina.sh run
# cleanup temp directory after stop
post-stop script
rm -rf $CATALINA_HOME/temp/*
end script
And that concludes our role definition. Now we can run the playbook.
[ansible@ansibleworkstation ~]$ ansible-playbook /etc/ansible/playbooks/tomcat7.yml --ask-vault-pass
Cleanup up is not automated at the moment, so if you want to experiment a bit, here are the instructions to clean up on a target host.
ansible@athena:~$ sudo service tomcat7 stop
tomcat7 stop/waiting
ansible@athena:~$ sudo rm -rf /etc/init/tomcat7.conf
ansible@athena:~$ sudo initctl reload-configuration
ansible@athena:~$ sudo rm -rf /usr/share/tomcat
ansible@athena:~$ sudo rm -rf /opt/apache-tomcat-7.0.72/
ansible@athena:~$ sudo userdel tomcat
ansible@athena:~$ sudo groupdel tomcat
groupdel: group 'tomcat' does not exist
As you can see, roles are very powerful and they can be customized with your own variables or with system facts. Enjoy !