3 minutes
Ansible for developers 102
Introduction
This page has been migrated to Medium
In the previous post we introduced basic aspects of Ansible. Now we’ll talk about some advanced features.
Loops
Another way to describe the tools of the Ansible family can be Infrastructure as code. This is the process of managing and provisioning computer data centers through machine-readable definition files, rather than physical hardware configuration or interactive configuration tools.
The word code brings an important aspect with it: loops.
In Ansible Playbooks you can use loops to reuse some tasks. An example can be the following:
- name: add several users
user:
name: "{{ item }}"
state: present
groups: "wheel"
loop:
- testuser1
- testuser2
This task adds several users and in order to do that, iterates over a loop. So you don’t have to write the same task twice.
You can iterate both on simple lists and on lists of maps. This can clarify this:
- name: add several users
user:
name: "{{ item.name }}"
state: present
groups: "{{ item.groups }}"
loop:
- { name: 'testuser1', groups: 'wheel' }
- { name: 'testuser2', groups: 'root' }
Using loops reduces the repetition in your playbooks, keeping them compact and clear.
Roles
Ansible Roles are ways of automatically loading certain vars_files, tasks, and handlers based on a known file structure. Grouping content by roles also allows easy sharing of roles with other users.
Roles are essentially a predefined directory structure that we’re utilizing to put individual pieces of our playbook into, to make it easier to reuse and share among groups.
An example directory structure can be the following:
webservers.yml
fooservers.yml
roles/
common/
tasks/
handlers/
files/
templates/
vars/
defaults/
meta/
webservers/
tasks/
defaults/
meta/
In this structure, we have the playbooks webserver.yaml
and fooservers.yml
and the roles common
and webservers
.
When in use, each directory must contain a main.yml
file, which contains the relevant content:
tasks
: contains the main list of tasks to be executed by the role;handlers
: contains handlers, which may be used by this role or even anywhere outside this role;defaults
: default variables for the role;vars
: other variables for the role;files
: contains files which can be deployed via this role;templates
: contains templates which can be deployed via this role;meta
: defines some metadata for this role. See below for more details.
Conventionally, the common
role contains a role that has to be run against all of your machines.
We can suppose that inside our roles/common/tasks/httpd.yml
we have the following:
- yum:
name: "httpd"
state: present
and that inside our roles/webservers/tasks/apache.yml
we have the following:
- apt:
name: "apache2"
state: present
Inside our playbook we will put:
---
- hosts: webservers
roles:
- common
- webservers
In that way, we included both common
and webservers
roles so that they can be executed when running the playbook.
With this small example, it’s hard to understand the benefits brought by roles, but as long as your playbook starts growing, you will find this structure a life-saving because you can reuse as much as you can, still keeping everything both clear and compact.
Ansible Galaxy
Ansible Galaxy is Ansible’s official hub for sharing Ansible content. Galaxy provides pre-packaged roles that can be dropped into Ansible PlayBooks and immediately put to work.
You may find roles for provisioning infrastructure, deploying applications, and all of the tasks you do every day.
Using the ansible-galaxy
command you can also create the role
structure. Once inside the roles
directory, you can run
$ ansible-galaxy role init my_role
to create the full structure for the role my_role
.
Conclusions
Now that you know those concepts you can be very productive using Ansible. So… good automation!