Skip to content

Roles

This is intended to be run during a dojo as a group exercise. However, it can be done individually

Take the following playbook and config file and break it down into the recommended folders and templates.

Notes

  • The default Tomcat user is tomcat. This sometimes changes depending on the server.
  • Decide how to make the server.xml into a jinja2 template.
  • There is a 'selinux' role dependency

playbook/test.yml

- hosts: localhost
  gather_facts: no
  tasks:
    - name: Install Java 1.7
      yum: 
        name: java-1.7.0-openjdk
        state: present
    - name: add group tomcat
      group:
        name: tomcat
    - name: add user tomcat
      user:
        name: tomcat
        group: tomcat
        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.j2
        dest: /usr/share/tomcat/conf/server.xml
      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 }}" 
handlers:
  tasks:
  - name: restart tomcat
    service:
      name: tomcat
      state: restarted
  - name: restart iptables
    service:
      name: iptables
      state: restarted 
server.xml
<?xml version='1.0' encoding='utf-8'?>

<!-- {{ ansible_managed }} -->
<Server port="8005" shutdown="SHUTDOWN">
 <Service name="Catalina">
    <Connector port="8090" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector port="8091" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    <Engine name="Catalina" defaultHost="localhost">
 </Service>
</Server>

init.sh

start(){}
status(){
}

stop() {
}

user_exists(){
}

case $1 in

        start)
          start
        ;;

        stop)
          stop
        ;;

        restart)
          stop
          start
        ;;

        status)
                status

        ;;

        *)
                echo -e $TOMCAT_USAGE
        ;;
esac
exit 0

input.json

{
    "http_port" : "8090"
    "https_port" : "8091"
}

Overall Structure

Initial Folder Breakdown
.
├── playbooks
│   └── test.yaml
└── roles
    └── tomcat-install
        ├── defaults
        ├── files
        ├── handlers
        ├── meta
        ├── tasks
        ├── templates
        └── vars

Playbook

This file normally contains the host, fact, and role information

Playbook Solution
- hosts: localhost
  gather_facts: no
  roles:
    - tomcat-install

Tasks

This directory contains one or more files with tasks that would normally be defined in the tasks section of a regular Ansible playbook. These tasks can directly reference files and templates contained in their respective directories within the role, without the need to provide a full path to the file.

Task Solution
- name: Install Java 1.7
  yum: name=java-1.7.0-openjdk state=present

- name: add group "tomcat"
  group: name=tomcat

- name: add user "tomcat"
  user: name=tomcat group=tomcat 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.j2 dest=/usr/share/tomcat/conf/server.xml
  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}}

Vars

Variables for a role can be specified in files inside this directory and then referenced elsewhere in a role.

Vars Solution
{   
    "http_port" : "8090"
    "https_port" : "8091"
}

Templates

This directory is reserved for templates that will generate files on remote hosts. Templates typically use variables defined on files located in the vars directory, and on host information that is collected at runtime.

Template Solution
<?xml version='1.0' encoding='utf-8'?>

<!-- {{ ansible_managed }} -->
<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
    <Connector port="{{ http_port }}" protocol="HTTP/1.1"
              connectionTimeout="20000"
              redirectPort="8443" />
    <Connector executor="tomcatThreadPool"
              port="8080" protocol="HTTP/1.1"
              connectionTimeout="20000"
              redirectPort="8443" />
    <Connector port="{{ https_port }}" protocol="HTTP/1.1" SSLEnabled="true"
              maxThreads="150" scheme="https" secure="true"
              clientAuth="false" sslProtocol="TLS" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    <Engine name="Catalina" defaultHost="localhost">
</Service>
</Server>

Meta

This directory is reserved for role metadata, typically used for dependency management. For example, you can define a list of roles that must be applied before the current role is invoked.

Meta Solution
---
dependencies:
  - selinux
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.
...

Files

This directory contains static files and script files that might be copied to or executed on a remote server.

Files Solution
start(){}
status(){
}

stop() {
}

user_exists(){
}

case $1 in

        start)
          start
        ;;

        stop)
          stop
        ;;

        restart)
          stop
          start
        ;;

        status)
                status

        ;;

        *)
                echo -e $TOMCAT_USAGE
        ;;
esac
exit 0

Handlers

All handlers that were in your playbook previously can now be added into this directory.

Handlers Solution
---
- name: restart tomcat
  service: 
    name: tomcat 
    state: restarted

- name: restart iptables
  service: 
    name: iptables 
    state: restarted
...

Defaults

This directory lets you set default variables for included or dependent roles. Any defaults set here can be overridden in playbooks or inventory files.

Defaults Solution
---
tomcat_user: tomcat
tomcat_group: tomcat
...

Completed Structure

Completed Structure Solution
├── playbooks
│   └── test.yml
└── roles
    └── tomcat-install
        ├── defaults
           └── main.yml
        ├── files
           └── init.sh
        ├── handlers
           └── main.yml
        ├── meta
           └── main.yml
        ├── tasks
           └── main.yml
        ├── templates
           └── server.xml.j2
        └── vars
            ├── input.json
            └── main.yml