Ansible runs tasks on remote nodes via SSH, and if you can’t use something like ControlMaster, processing large numbers of tasks on nodes can take a while.

Michael DeHaan recently introduced something he’s called fireball mode, which dramatically increases Ansible’s throughput in handing-off tasks for nodes to run. Fireball mode is not quite finished yet, but it works and it’s already quite impressive.

Ansible fireball mode

Upon starting up a playbook, Ansible launches an ephemeral daemon on the target nodes. This daemon will stay up for a configurable time (default is 30 minutes), and it sets up a 0mq listener on port 5099 (configurable as well) to wait for Ansible to fire tasks at it, which the remote node then runs just as it does over SSH: nothing changes here. 0mq support in fireball mode basically consists of a wrapper around low-level socket operations, and authentication is handled by AES keys which are computed for each host and generated for each user running Ansible.

Getting fireball mode set up on a remote node is easy enough, using Ansible itself. The following playbook installs the required Python modules on the target hosts. I do this via SSH.

---
- hosts:
  - a1.ww.mens.de
  gather_facts: false
  connection: ssh
  user: f2
  sudo: True
  tasks:
  - action: easy_install name=pip
  - action: pip name=pyzmq state=present
  - action: pip name=pyasn1
  - action: pip name=PyCrypto 
  - action: pip name=python-keyczar

Once that is complete and the Python modules exist on the management host as well, we can go ahead and try fireball mode.

---
- hosts:
  - a1.ww.mens.de
  gather_facts: false
  connection: ssh
  user: f2
  sudo: yes
  tasks:
  - action: fireball

- hosts:
  - a1.ww.mens.de
  connection: fireball
  tasks:
  - action: shell echo "Hello {{item}}" 
    with_items:
    - one
    - two
  - action: template src=u2.in dest=/tmp/t.{{item}} mode=0600
    with_items:
    - one
    - two

This playbook consists of two plays:

  1. The first play connects to remote nodes via SSH and launches the ephemeral fireball daemon. Note the fireball action as well as the sudo: yes: the node will launch the fireball daemon with sudo, enabling subsequent tasks to run as root. (By the way, fireball’s PID is located in ~/.fireball.pid if you want to see which process is actually doing the hard work on the node.)
  2. The second play in the playbook is where I launch the individual Ansible tasks against the nodes. Because we started the fireball daemon as root in the first play, these tasks will all be run as root, and I don’t have to specify connection parameters for this play (no user either).

Initial tests with 200 tasks to run against a host took 42 seconds of wall-clock time via SSH, and 17 seconds of wall-clock time using fireball mode. That’s quite a difference!

This increase in speed comes at a cost: the setup-free installation which Ansible provides out of the box turns into a bit more work: nodes need the appropriate Python modules installed (easily accomplished using Ansible itself, as I demonstrated above), and an additional firewall port has to be open for 0mq traffic to pass through. Even so, if you feel “plain” Ansible (i.e. using SSH) is too slow for you, give fireball mode a try. It’s currently available in the Git development branch, but should be released when Ansible 0.8 arrives.