Using Ansible Locally as a Parallel Scripting Engine

If you are familiar with Ansible, you are probably aware that it is essentially a multi-host SSH scripting tool. The fact that it has modules that can be abstracted from the operating system occasionally makes it useful locally. However, in most cases using it locally has little more effect than simply writing a shell script.

There is, however, as way to change that. Ansible has a built in looping construct that is very useful in writing playbooks, and which is described here. However, control of that loop is dependent on the module that executes the loop or hash. This means that you cannot easily write a number of custom shell scripts, execute them locally in parallel, wait for them to finish, and then move on. The trick to actually doing this is to use multiple local hosts. By running the entire play against multiple local hosts you can achieve the same type of scripting flow that you have with external hosts locally. Every task in a role can be run in parallel.

What does it look like when you run multiple local tasks in parallel, and how do you do it? The starting point is that you need to use the localhost subnet to your advantage. Generally, 127.0.0.1 and perhaps 127.0.1.1 are configured in /etc/hosts, but you aren’t limited to that. You can use the entire 127.0.0.0/8 space if you desire. For an example of this try the following command:

ansible -i 127.0.0.2,127.0.0.3, all -m ping --extra-vars 'ansible_connection=local'
Screenshot of Ansible output

What is going on in the above example?

  1. I’m just running the ansible command line tool to keep things simple, not a playbook or role.
  2. I’m using a local inventory provided at the command line. The option -i 127.0.0.2,127.0.0.3, uses two hosts by address, with comma separation and a railing comma, to indicate that I’m listing hosts directly, instead of an inventory file. Because I’m using IP addresses, there’s no need to put named ntries in /etc/hosts, although doing so would probably be helpful.
  3. I’m running the basic ping module against all hosts, which is the simplest demonstration possible.
  4. The last item, –extra-vars ‘ansible_connection=local’ is necessary because we aren’t using SSH to connect to local addresses.
  5. The output clearly shows how this works.