1 Objective

This exercise looks at ways you can use ansible in larger environments, in particular how you can use "roles" to make your configurations more reusable.

1.1 Setup

Make sure you are logged into your master ansible machine over SSH with agent forwarding enabled. You should be logged in as your normal non-root user ("sysadm").

Also make sure that from this host, ansible is able to login as root to all the other machines you are managing. To test this:

ansible all -m shell -a id

2 Roles

Now we will make a new playbook broken down into "roles". These are reusable pieces of configuration.

You will do the following as the "sysadm" user. Check you are in your home directory:

pwd   # should show /home/sysadm

If necessary, use "cd" to change to the right directory.

Now make a directory called "roles", and change into it:

mkdir roles
cd roles

Inside this create a directory called "webserver", which is the role we are going to make:

mkdir webserver
cd webserver

Inside this create a directory called "tasks":

mkdir tasks
cd tasks

Check that you are inside this directory:

pwd   # should show /home/sysadm/roles/webserver/tasks

Finally, inside this directory create a file called main.yml using a text editor. The file should look like this:

- name: ensure package cache is up to date
  action: apt update_cache=yes cache_valid_time=3600
  tags: install
- name: install web server
  action: apt pkg=apache2 state=present
  tags: install

Notice this is just what we put in the 'tasks:' section of our playbook, but moved to the left so that the dashes are in the first column (because these tasks are not nested within any other YAML)

2.1 Test

You cannot directly invoke a role by itself, you have to include it in a playbook. This means you need to need to write a little playbook to use it.

First, move back up to your home directory:

cd
pwd   # should show /home/sysadm

Create a file call testweb.yml

- hosts: hostXXX.ws.nsrc.org
  roles:
    - webserver

And run it:

ansible-playbook testweb.yml

Did it work? If not, have a look at the error and ask for help if you need it.

2.2 Adding templates

If you remember, our webserver also included an index.html file. Let's do that in the role as well.

Move back into the "tasks" directory:

cd roles/webserver/tasks
pwd   # should show /home/sysadm/roles/webserver/tasks

Edit your existing main.yml file and add the following to the end:

- name: install index page
  template: src=front.html dest=/var/www/html/index.html backup=yes
  tags: configure

But now the role needs a front.html file. This will live in a separate templates directory, which sits alongside the tasks directory.

So now move up one level:

cd ..
pwd  # should show /home/sysadm/roles/webserver

If you find you are in the wrong directory, then you can just change directory to the right place:

cd /home/sysadm/roles/webserver

Now create a subdirectory called "templates" and enter it:

mkdir templates
cd templates

Inside this directory, create a file called front.html with the following contents:

<html>
<head><title>Hello world</title></head>
<body>
{% if server_role is defined %}
This server is acting as {{ server_role }}
{% else %}
I don't know what I am!
{% endif %}
</body>
</html>

2.3 Handlers

Roles can also have handlers; you need another subdirectory ("handlers") and file (main.yml)

cd
cd roles/webserver
mkdir handlers
cd handlers
pwd   # should show /home/sysadm/roles/webserver/handlers

# Use your editor to create a file "main.yml" in this directory
# with the following contents
- name: restart apache2
  service: name=apache2 state=restarted

Now go back you your tasks/main.yml

cd ../tasks

# Edit main.yml and add a "notify" line, so that the install index page
# task looks like this:
- name: install index page
  template: src=front.html dest=/var/www/html/index.html backup=yes
  tags: configure
  notify: restart apache2

Test it as before.

2.4 Default variables

cd
cd roles/webserver
mkdir defaults
cd defaults
pwd   # should show /home/sysadm/roles/webserver/defaults

# Use your editor to create a file "main.yml" in this directory
# with the following contents
server_role: primary webserver

Now any template expansion using {{ server_role }} will use the text primary webserver, unless another value has been given (e.g. in the inventory or host_vars/group_vars)

2.5 Review

Now check all the files you have created in the "roles" directory:

cd 
find roles -type f

This should show you have created the following files:

roles/webserver/tasks/main.yml
roles/webserver/templates/front.html
roles/webserver/handlers/main.yml
roles/webserver/defaults/main.yml

Each role therefore consists of a number of subdirectories and files, all inside a single top directory for the role name.

3 Additional information

3.1 Sharing roles

You can create multiple playbooks, and each of them can share the "roles" subdirectory in the same directory.

If you want to have roles shared by everyone on the system, put them in a common directory and then set "roles_path" in /etc/ansible/ansible.cfg

For example, you might put all your roles under /etc/ansible/roles and then edit /etc/ansible/ansible.cfg to include:

# additional paths to search for roles in, colon seperated
roles_path    = /etc/ansible/roles