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.
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
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)
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.
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>
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.
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)
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.
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