ansible

Safely limiting Ansible playbooks to a single machine?


I'm using Ansible for some simple user management tasks with a small group of computers. Currently, I have my playbooks set to hosts: all and my hosts file is just a single group with all machines listed:

# file: hosts
[office]
imac-1.local
imac-2.local
imac-3.local

I've found myself frequently having to target a single machine. The ansible-playbook command can limit plays like this:

ansible-playbook --limit imac-2.local user.yml

But that seems kind of fragile, especially for a potentially destructive playbook. Leaving out the limit flag means the playbook would be run everywhere. Since these tools only get used occasionally, it seems worth taking steps to foolproof playback so we don't accidentally nuke something months from now.
Is there a best practice for limiting playbook runs to a single machine? Ideally the playbooks should be harmless if some important detail was left out.


Solution

  • Turns out it is possible to enter a host name directly into the playbook, so running the playbook with hosts: imac-2.local will work fine. But it's kind of clunky.

    A better solution might be defining the playbook's hosts using a variable, then passing in a specific host address via --extra-vars:

    # file: user.yml  (playbook)
    ---
    - hosts: '{{ target }}'
      user: ...
    

    Running the playbook:

    ansible-playbook user.yml --extra-vars "target=imac-2.local"
    

    If {{ target }} isn't defined, the playbook does nothing. A group from the hosts file can also be passed through if need be. Overall, this seems like a much safer way to construct a potentially destructive playbook.

    Playbook targeting a single host:

    $ ansible-playbook user.yml --extra-vars "target=imac-2.local" --list-hosts
    
    playbook: user.yml
    
      play #1 (imac-2.local): host count=1
        imac-2.local
    

    Playbook with a group of hosts:

    $ ansible-playbook user.yml --extra-vars "target=office" --list-hosts
    
    playbook: user.yml
    
      play #1 (office): host count=3
        imac-1.local
        imac-2.local
        imac-3.local
    

    Forgetting to define hosts is safe!

    $ ansible-playbook user.yml --list-hosts
    
    playbook: user.yml
    
      play #1 ({{target}}): host count=0