Skip to content

Ansible


Having control over configuration enables unprecedented levels of visibility and security around your Cloud infrastructure. Compare this to the hidden, silent changes made using manual intervention which almost always goes undocumented and unseen.

It's also the very definition of automation, which ships with its own inherent benefits. These include saving time, huge reductions in (human) errors, and reproducibility. All three of these examples also save you money (and a lot of it.)

And the code, the automation, can be reused over and over even as your architecture changes or as new projects are required within your organisation. Now other projects and businesses within your scope are getting quick wins from the work you've already done.

Finally you gain the security of reducing the amount logins to consoles or APIs for making changes. Everything can (and should) be done through code, peer reviews, branch merging strategies, and CI/CD, reducing everyone's access to a Git repository, not a complex web of ACL policies.

Ansible

Ansible is an open-source tool for managing the configuration of operating systems and software as code. Using YAML to define state, which in turn is done by using modules (of code), a system administrator can quickly, easily, and securely manage a large estate of servers of all shapes and sizes. Ansible has a huge ecosystem and community as well as being owned and powered by RedHat.

Back in the day system administrators would manually configure servers. This introduced a lot of problems, namely:

  1. More often than not, those changes were never documented
  2. Changes would often be put in place without the knowledge of other team members
  3. No one was consulted nor reviewed changes before they were put into place
  4. Outages often resulted in hours of wasted debugging and analysis

Ansible helps to completely abolish this type of working, replacing it with a new way:

  1. Ansible is code, so your changes are documented in that code
  2. You push your Ansible code to GitLab and use Merge Requests to get a code review before committing changes
  3. Everyone can be consulted and with protected branches in GitLab, a minimum number of eyeballs can be applied to a change before it's used
  4. Outages can be linked directly to the last commit to your Ansible code – there's the issue in plain sight, in seconds

So what can Ansible do?

Features

Let's review some of Ansible core features.

Single One-Off Commands

Ansible can be used to issue one-off commands to multiple (thousands) of systems at once. An example of this might be to add a new user to a cluster of Linux servers. A single command can be used to get those users in place.

You can also use one-off commands to get information about a vast array of servers in one swoop.

With that said, you're almost always better off using Playbooks and Roles, which are made up of many modules to get your work done for you.

Modules

Ansible has hundreds of built in modules for managing thousands of resources, such as users, services, packages, files, PostgreSQL databases, AWS EC2 Instances (not recommended; see "What is Terraform?"), and more.

It ships with a lot managed, core modules but the community is also extremely healthy and active when it comes to other requirements. More often than not, you'll be able to find a module that does what you need or comes extremely close. being open source, you can clone such modules and make them work for you.

Modules are super easy to develop and are written in Python.

Playbooks

A Playbook is a contained set of instructions for Ansible to execute. These instructions call upon Roles and Modules to get work done. Playbooks are the primary means by which an administrator would manage their estate.

They can be executed against any number of systems to do any number of things. For example a Playbook can be used to install, configure and start a WordPress installation. This includes managing users, packages, databases, files systems, and services. Such a Playbook is useful in a lot of different contexts.

Playbooks enable us to write repeatable code. This code can be shared, peer reviewed, automated, and so on. Because it's code, you get a lot of benefits out of the box.

Playbooks are also capable of pulling information from multiple sources before executing modules or using Roles. This means the same Playbook can be run with different inputs depending on the environment being configured.

A Playbook is made up of instructions, but these instructions are stored in something called a Play. The following Playbook has one Play. A Playbook can have multiple Plays:

1
2
3
---

- hosts: all

We define Plays by creating a list of objects. If you look at line 3 above, you'll see we're defining a list in YAML syntax. This list has a single item: an object or dictionary. Or in other words a Play.

Hosts

Inside of our Play we have defined a hosts key. This is also present on line 3.

We've set this to all, which is a special keyword to tell Ansible to target everything. Using the hosts key you can do some very specific things. It targets the things you've defined in your inventory.

You can target specific hosts by name; groups by name; or use logic to include or exclude specific items from your inventory. It can get complex but I recommend you keep it as simple as possible. Check out the Ansible documentation on using patterns.

Become

The become keyword tells Ansible whether or not to switch over to the root user, or whatever the super user is on the system, before executing commands. Almost everything we're doing requires higher privileges, so we've set it to a value of yes. However as you'll see below we also turn this flag "off" for specific tasks.

1
2
3
4
---

- hosts: all
  become: yes
Tasks

This keyword, tasks, lists everything we want Ansible to do for us. There are other keywords that do something similar, like roles, pre_tasks, etc., but we'll come to those when we need them.

1
2
3
4
5
---

- hosts: all
  become: yes
  tasks:

We're using the tasks keyword to list the state we want. This keyword is a list of objectives, like our list of Plays that comprise the Playbook, and a task takes on this format (possibly not complete):

This object is made up of several keywords, some of them nested deeper again in the object (producing another object).

  • name - this is the name of the task and what is printed in the CLI
  • apt - this is the name of the module you want to execute, in this case apt which is for managing packages on Debian based systems (like Ubuntu)
  • apt.name - the name of the package we want apt to manage for us
  • apt.status - how we want the package to be managed, such as uninstalled, installed, updated
  • loop - a special keyword that loops over a list of strings and feeds them into apt.name (that's what `` is doing)

Here's the first task in our Playbook, which is inside the first Play:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
---

- hosts: all
  become: yes
  tasks:
    - name: Update all packages and the system package cache
      apt:
        name: "*"
        state: latest
        update_cache: yes

Roles

Roles are essentially a collection of Playbooks, configuration, and dependencies like files and scripts. They're a great way of managing a single resource, such as PostgreSQL or Nginx, and can be used throughout many Playbooks for many different goals.

When you combine multiple Roles into a single Playbook, you can begin to manage complex estates with ease. Such set ups make it easy to understand why something is configured the way it is, and how. Changes are introduced with simple code changes.

And there's a whole community chest of Roles available for consumption today. Some are very high quality and well maintained. These Roles are also open source and can be cloned and adopted to your specific needs easily.

The (Dynamic) Inventory

Ansible uses the concept of an Inventory to understand what servers you have, how they're related (if at all), and how to connect to them. Ansible connects to the systems in the inventory using SSH and executes Modules against the remote host.

This inventory can be simple or complex, comprising of groups and sub-groups. A simple Inventory might just be a flat file on disk in INI format. This flat file can be managed manually and updated when new systems are introduced or old one decommissioned.

But this Inventory can can also be dynamic, pulling and constructing its information from remote data sources, such as AWS, every time you execute Ansible. This is much more powerful and flexible, enabling Ansible to just scale with your own business growth.

Summary

Moving away from error prone, slow and expensive manual processes is within your interest and something you should already be doing.

Ansible is very powerful and offers unlimited flexibility and expansion. It's the very definition of Configuration As Code and is considered industry standard by most at this point.

Next

If you've got Ansible installed already or you're a seasoned professional you're welcome to skip the next section. If not then let's look at getting Ansible installed on your local system.


Last update: August 29, 2021