Skip to content

Playbook Strategies


Every playbook in this course, all the way back to the very first one, has quietly relied on a specific execution model without ever naming it. This chapter names it, and covers two genuinely different alternatives.

The Default: linear

Recall from the very first playbook chapter: with more than one host, each task completes on every targeted host before any host moves on to the next task — hosts that finish early wait for slower ones to catch up, and the play proceeds task by task, in lockstep. This is the linear strategy, Ansible’s default, used implicitly in every playbook this course has built so far.

- name: Explicit Linear
  hosts: servers
  strategy: linear
  tasks:
    - name: Task one
      ansible.builtin.debug:
        msg: "..."

free: Each Host Races Ahead Independently

strategy: free removes the lockstep entirely — each host proceeds through the whole task list at its own pace, with no waiting on any other host at all:

- name: Free Strategy Demo
  hosts: servers
  strategy: free
  tasks:
    - name: Task one
      ansible.builtin.debug:
        msg: "..."
    - name: Task two
      ansible.builtin.debug:
        msg: "..."

A fast host can finish every task while a slow one is still on the first — genuinely useful when hosts have meaningfully different performance characteristics, and there’s no real reason for a fast host to sit idle waiting on a slow one.

A Realistic Consequence Of free

This isn’t free of tradeoffs — the name is a description of behavior, not a recommendation. Terminal output becomes genuinely interleaved and unpredictable under free. More importantly, any assumption that “by the time task N runs, every host has already finished task N-1” is no longer safe. This matters directly for handlers (which normally run at a play’s end — a point that now arrives at different times for different hosts) and for delegate_to patterns, covered in the next chapter, where a task might implicitly assume some other host has already reached a certain point. free is a deliberate tradeoff, not a default to switch to lightly.

The debug Strategy: Automatic Debugging On Every Failure

strategy: debug behaves like linear, but automatically drops into the interactive debugger, from the troubleshooting and debugging section, on every task failure across the whole play — without needing debugger: on_failed set individually anywhere:

- name: Debug Strategy Demo
  hosts: servers
  strategy: debug
  tasks:
    - name: Task one
      ansible.builtin.debug:
        msg: "..."

debug Strategy vs. debugger: Keyword — Don’t Confuse The Two

Worth a dedicated, explicit note, since the naming genuinely collides. debugger: is a per-task, per-block, or per-play keyword, controlling exactly when the interactive debugger triggers for whatever it’s attached to, with fine-grained trigger conditions (on_failed, on_unreachable, on_skipped, always). strategy: debug is a whole-play execution model, which happens to also enable debugger-on-failure behavior across everything, as a side effect of using it. They overlap in effect for the on-failure case, but they’re conceptually different mechanisms — one configures a trigger, the other replaces how the entire play executes.

Setting A Strategy

A play-level keyword, as shown throughout this chapter — or set globally via ansible.cfg:

ansible.cfg
[defaults]
strategy = free

Per-play is more common and more deliberate; a global default in ansible.cfg applies silently to every play that doesn’t explicitly override it, which is worth being cautious about.

Best Practices

  • Leave strategy at its default (linear) unless you have a specific reason to change it — most playbooks, especially anything involving handlers or delegate_to, rely on linear’s lockstep guarantees whether or not that was ever consciously noticed.
  • Use free specifically when hosts genuinely have very different per-task durations, and there’s no coordination dependency between them.
  • Prefer debugger: on_failed on specific tasks over strategy: debug for routine troubleshooting — reserve strategy: debug for deliberately investigating an entire unfamiliar play end to end.
Last updated on