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 nginx, Jenkins and other.
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
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.
- Hackintosh – The Hardware - 22/02/2020
- Installing Artifactory with Docker and Ansible - 17/08/2018
- Docker Networking – Overlay Network - 15/08/2018