Saturday, 31 October 2015

Ansible's for loops

Recently, me and a team hit a big limitation with Ansible that really took me by surprise.  For loops, can only iterate over a single task and not roles or playbooks.  This post will discuss why it was a surprise, what we did to get around it and (briefly) what Ansible 2 introduces.

Pre Ansible 2

The original issue really took me by surprise since the documentation on for loops showed a huge number of possibilities (including conditionals, looping over arrays etc etc) that suggested to me it was Turing-Complete and easily capable of meeting all our looping needs.  So when I needed to assign a role multiple times (dynamically from a list) I was shocked to find that it couldn't be done.

I'm not the only one who was caught out by this.  See here, here and here.

Why this wasn't supported really puzzled me.  Some on my team concluded that it must be due to the way Ansible works internally and would perhaps require a lot of re-writing to support the feature.  However, Michael DeHaan said here that there was a "fundamental reason" it couldn't be done:

"...the role must be applied in the same definition (but not the same variables) to each host in the host group. Ergo, you can't have different numbers of roles applied to different hosts in the same group based on some kind of inventory variance."

But I don't understand why you can't.  The hack here suggests to me that you can.

Should the docs have told me what's not possible?

I also wondered if the ansible documentaion on loops should have mentioned its limitations.  Funnily enough, Michael DeHaan wrote an article on Technical Documentation As Marketing which said "your documentation and front material is there to both be honest, communicate how to use something, and also sell what you are doing".  The docs certainly didn't lie to me, but they could have been more honest about limitations.


We looked at a few options:

  1. Hack - Way too ugly!
  2. Loop over each task within a role separately - This was not possible for us since some tasks depended on output from previous tasks. 
  3. Convert role (or set of tasks) into a single task - No appetite to learn and code more ansible specific stuff at a time when we felt so let down by it!
  4. Move logic away from ansible into something external that ansible calls (e.g. a bash script).  
We opted for the least bad, which to us was option four.  

Post Ansible 2

According to slide 15 here, in Ansible 2 you can loop over multiple tasks which is really good to hear.  However, it seems you can only loop over tasks, and not roles.  I don't understand why you can't loop over roles, but am really encouraged to see the feature included.  It's also great to hear that Ansible 2 is backwards compatible with version 1.  I look forward to using it. 


  1. I think the official recommendation is: Writing your own iterators ;-)

  2. This works:

    ...but not on rule level: you need to create a subtask and iterate over subtask.yaml from main.yaml :-)

  3. Thanks for the post, for Ansible training through online visit Tekslate.

  4. Ansible Training expertise and make you learn all that is required to provision, deploy, and manage compute infrastructure across cloud, virtual,
    and physical environments. Ansible further help you build a strong foundation for DevOps.
    Ansible is an automation and configuration management technology used to provision, deploy, and manage compute infrastructure across
    cloud, virtual, and physical environments. In this course, students will learn the basics of Ansible and watch a simple Ansible playbook being created from
    beginning to finish.

    Ansible Architecture

    Ansible distinguishes two types of servers: controlling machines and nodes. It works by connecting to your hosts and pushing out small programs,
    called “Ansible Modules”. These programs are written to be resource models of the desired state of the system. The controlling machine describes the location
    of nodes through its inventory. Ansible then executes these modules (Nodes are managed by a controlling machine over SSH).

    Design goals:

    The design goals of Ansible include:

    Minimal in nature.
    Low learning curve
    Highly reliable