Ansible is an easy to use configuration management system that can assist you in configuring large numbers of servers from a single machine. You can automate complex tasks and easily add machines to your infrastructure without too much trouble.
In a previous guide, we discussed about the basics of Ansible. In this guide, we will discuss how to use Ansible roles to allow you to break up configuration into more modular steps.
We will assume that you have a configured Ansible server and a few clients, just as we left off in the last guide.
What are Ansible Playbooks?
Ansible playbooks are a way to send commands to remote computers in a scripted way. Instead of using Ansible commands individually to remotely configure computers from the command line, you can configure entire complex environments by passing a script to one or more systems.
What is an Ansible Role?
You’ve been exposed to how Ansible can interact with configured clients from the command line using the ansible (It’s a command and hence it’s not capital) command, and how you can automate configuration with playbooks run through the ansible-playbook command.
Simply put, roles are a further level of abstraction that can be useful for organising playbooks. As you add more and more functionality and flexibility to your playbooks, they can become unwieldy and difficult to maintain as a single file. Roles allow you to create very minimal playbooks that then look to a directory structure to determine the actual configuration steps they need to perform.
Creating the Role Framework
In order for Ansible to correctly handle roles, we need to build a directory structure that it can find and understand. We can do this by creating a “roles” directory in our working directory for Ansible.
Within this directory, we are going to define our roles. We will basically create a directory for each role.
cd ~ mkdir roles cd roles
Since we are going to replicate our Nginx playbook, let’s create an Nginx role using the ansible-galaxy command:
ansible-galaxy init nginx
It will create the following directories in the nginx directory :
mkdir files handlers meta templates tasks vars
This is what the directories are for:
files: This directory contains regular files that need to be transferred to the hosts you are configuring for this role. This may also include script files to run.
handlers: All handlers that were in your playbook previously can now be added into this directory.
meta: This directory can contain files that establish role dependencies. You can list roles that must be applied before the current role can work correctly.
templates: You can place all files that use variables to substitute information during creation in this directory.
tasks: This directory contains all of the tasks that would normally be in a playbook. These can refer files and templates contained in their respective directories without using a path.
vars: Variables for the roles can be specified in this directory and used in your configuration files.
Create a Skeleton Playbook
Now that we have configured our role structure, we can call all of the functionality with a very simple playbook.
This allows us to use playbooks to declare what a server is supposed to do, not what steps must happen to make it behave how we want it to.
Outside of the entire role structure, in our working directory (our home directory in this example), we can create a playbook file.
cd ~ vim play.yml
Inside of this file, we need very little information. First, we have not defined any hosts, so that goes here. Next, we just declare the role we are using:
--- - hosts: webservers roles: - role: nginx
Save and close the file. This is our entire playbook. As you can see, it cleans everything up and allows us to concentrate on core functionality.
Since in the end, we use a playbook to call a role, the command syntax is exactly the same:
Ansible roles are an optional feature to take advantage of, but if you plan on using Ansible extensively, it is highly recommended that you explore this functionality. Not only will it keep your host-level configuration clean and readable, it will also allow you to easily reuse code and implement your changes in a modular fashion.