Keeping it simple – the Ansible automator
The Easiest Way
Getting Started with Ansible
The lack of a client-server architecture, from an admin's point of view, makes getting started with Ansible a quick experience, given a user with an SSH-based login on all systems and permission to run sudo
without a password. On any system that can access the other systems over SSH, you then install the Ansible package intended for your distribution. Because Ansible has now reached a very wide level of distribution, you can choose from packages for all common Linux systems. After that, calling ansible-playbook
should take you to a matching help text.
The next step is to create an inventory. You can store this either in YAML or INI format. The inventory is divided up into host groups, for which the names are the block headers. The code in Listing 1 creates an inventory with two host entries that belong to the lmtest
group. The ansible_user
directive instructs Ansible to log on to the host as the mloschwitz
user. The
ansible -i <file> all -m ping
command then pings all the hosts from the inventory. The <file>
argument specifies the name of the inventory file – which is normally hosts
.
Listing 1
Inventory (excerpt)
<pre> [lmtest] server1.local ansible_user=mloschwitz server2.local ansible_user=mloschwitz <pre>
Directory Structure
The Ansible developers provide useful insights in the documentation [1] on how the admin should ideally design the Ansible directory. The example provides for a folder containing a file named hosts
. The first playbook – in the example, lmtest.yml
– is located at the same directory level, as is an Ansible vault file (more on that later). Great importance is given to two additional folders, host_vars/
and group_vars/
, the latter of which is used to create files whose names match the groups defined in the inventory.
The group in the example is named lmtest
; variables could be defined for this group in the group_vars/lmtest
file. Files for the individual hosts (e.g., server1.local.yml
) are stored in host_vars/
. It is important to always use the full hostname as it appears in the inventory; otherwise, Ansible fails to establish the connection between the file and the host and fails with an error message because variables are not defined.
The last folder needed is the most important one, roles/
, which you use to create roles that perform individual steps on the target systems. Although you could also add the roles tasks directly to your playbooks, doing so would become confusing over time. Therefore, it has become common practice to write roles that handle logically related tasks on the setup's servers. In the roles/
folder are subfolders with the names of the roles (e.g., lmtestrole
). These folders also have a specific structure.
The most important folder for a role, tasks/
, has at least one file named main.yml
that optionally contains includes to other files in the same directory or the desired tasks directly. The task of installing a package on a target system would look something like Listing 2 in the lmtestrole/tasks/main.yml
file.
Listing 2
Package Installation
<pre> - name: Install helloworld package: name: hello-world state: present <pre>
Task entries, and all entries in Ansible in general, follow a similar pattern: name
with a short description, then the module to be called, and finally its parameters. The structure of a role in Ansible is similar to that of a shell script, a fact that significantly lowers the barriers to entry for automation novices. The mandatory name
entry also makes Ansible roles at least partially self-documenting, which makes them understandable to people other than the authors themselves.
The example shown here covers only a fraction of Ansible's functionality. For example, in the tasks/
folder within the role, you could define triggers that start, stop, or restart services. With the notify
parameter in the task, you could call the defined trigger afterward. The templates/
and files/
folders are equally important, if you need them. Files that need to find their way onto the systems unchanged end up in files/
. In contrast, templates/
contains placeholders in various places that Ansible dynamically replaces with the value that applies for the host before rolling the results out to a host. In this way, you only need one template to roll out the configuration file to multiple hosts with the appropriate IP for each host.
Predefined Variables
To help the administrator do just that, Ansible defines a variety of environment variables per host. In Ansible jargon, these are known as facts , but accessing them works like accessing normal variables.
For example, one often-used variable is ansible_distribution
, which tells the admin in the module whether they are dealing with Debian, Ubuntu, CentOS, or SUSE. With the help of the ansible_distribution_version
fact, you can additionally check the specific version. Ansible only executes the items where when
conditions are possible if the criteria specified in the condition are true.
Using the facts described here, an admin could design the role such that Ansible performs certain tasks on specific distributions only, which makes working with Ansible in a heterogeneous environment far easier.
Buy this article as PDF
(incl. VAT)