How to use Ansible Roles

Ansible Galaxy

In the Ansible introduction, we build a Playbook to install Jenkins from scratch on a remote machine. The Playbook was simple (for education purposes), it was designed for Debian Linux distributions (we used apt as a package manager), it just provided an out-of-the-box Jenkins (without any customisation). Thus, the Playbook is not very re-usable or configurable.

However, if we would have made it more complex, the single-file Playbook would have become difficult to read and maintain and thus more error-prone.

To overcome these problems, Ansible specified a directory structure where variables, handlers, tasks and more are put into different directories. This grouped content is called an Ansible Role. A Role must include at least one of these directories.

You can find plenty of these Roles design by the Ansible community in the Ansible Galaxy. Let me show some examples to explain the concept of Ansible Roles.

How to use Roles

I highly recommend using popular Ansible Roles to perform provisioning of common software than writing your own Playbooks, as it might be more versatile and less error-prone, e.g. to install Java, Apache or nginxJenkins and other.

Ansible Galaxy
Ansible Galaxy

Let us assume we want to install an Apache HTTP server. The most popular Role with over 300.000 downloads was written by geerlingguy, one of the most popular contributors to the Ansible Galaxy. I will jump right into the GitHub Repository of this Role.

Firstly, you always have to install the role using the command line,

ansible-galaxy install [role-name] e.g.

ansible-galaxy install geerlingguy.apache

Roles are downloaded from the Ansible Galaxy and stored locally at ~/.ansible/roles or /etc/ansible/roles/ (use ansible --version if you are not sure).

In most cases, the README.md provides sufficient information on how to use this role. Basically, you define the hosts, on which the play is being executed, the variables to configure the role, and the role itself. In case of the Apache Role, the Playbook (ansible.yml) might look like this

- name: Install Apache

  hosts: web1

  become: yes
  become_method: sudo

  vars:
    apache_listen_port: 8082

  roles:
    - role: geerlingguy.apache

web1 is a server defined in the Ansible inventory, I set-up with Vagrant before. Now you can run your Ansible Playbook with

ansible-playbook apache.yml

In a matter of seconds, Apache should become available at http://[web1]:8082 (in my case: http://172.28.128.3:8082/).

Since Ansible 2.4 you can also include Roles as simple tasks. The example above would look like this

- name: Install Apache

  hosts: web1

  become: yes
  become_method: sudo

  tasks:
  - include_role:
       name: geerlingguy.apache
    vars:
       apache_listen_port: 8082

A short Look inside a Role

I won’t go too much into how to design Roles, as the Ansible documentation already provides a good documentation. Roles must include at least one of the directories, mentioned in the documentation. In reality, they look less complex, e.g. the Apache Ansible Role we used in this example, looks like

Directory Structure of Ansible Role to install Apache
Directory Structure of Ansible Role to install Apache

The default-variables including a documentation are defined in defaults/main.yml, the tasks to install Apache can be found in /tasks/main.yml, that in turn calls the OS-specific Playbooks for RedHat, Suse, Solaris and Debian.

Further Remarks

Ansible Roles give good examples of how to use Ansible Playbooks in general. So if you are new to Ansible and want to understand some of the concepts in more detail, I recommend having a look at the Playbooks in the Ansible Galaxy.

As mentioned above, I highly recommend using pre-defined roles for installing common software packages. In most cases, it will give you fewer headaches, especially if these Roles are sufficiently tested, which can be assumed for the most popular ones.

 

Chris