Have ansible skip running a play on the machine running the Ansible playbook

Viewed 913

How can I construct a playbook so an individual play is NOT executed on the machine where Ansible is running from?

For instance, if I have a simple two-play playbook:

- name: Patch and reboot
  hosts: all
  gather_facts: true

  tasks:
  - name: Fully patch system
    package:
      name: "*"
      state: latest
    become: true
    register: patchstatus

  - name: Reboot if patched
    reboot:
    become: true
    when: patchstatus is changed

But I don't want the reboot to trigger if it is running on the machine running Ansible.

I know that a better maintained inventory wouldn't have my Ansible system in with the others, but this is a lab and I want a simple playbook I can fire off nightly - I'd rather it not reboot my Ansible playbook (at least not until it's the last one to reboot).

Simply put, I am looking for a pre-defined variable so I can use a simple when: ansible_hostname != ansible_execution_server could be simply used to skip the play. (Assuming ansible_execution_server is the name of the system that ansible-playbook is executing from.)

Then the reboot section could be this:

  - name: Reboot if patched
    reboot:
    become: true
    when:
      - patchstatus is changed
      - ansible_hostname != ansible_execution_server
2 Answers

If you're not being targeted by an existing Inventory file when you run your Playbook, then your workstation is being targeted by the Implicit Localhost.

The behavior you're experiencing is because the global hosts variable is set to all. Which, as you probably know, specifies that each task should run on all hosts in your inventory.

If you don't want the reboot to trigger on the machine running the Playbook, then you need to ensure that it is excluded from it. This is commonly done with Groups in an inventory file.

I'm am relatively familiar with using Ansible inventory files and I have never ran into a situation where using one adds the limitations that you describe in the last paragraph of your description.

First of all, here is the documentation for Ansible Inventory files. I know Ansible documentation is very verbose. But a lot of the finer workings of Ansible are nuanced and if you normally search through docs for specific implementation information you might miss a lot of context. I encourage you to read the entire document before proceeding if you haven't already.

After that, build an inventory file like so:

[hardware]
my.router.name
my.switch.name
my.computer.name
my.first.server
my.second.server
my.third.server

[networking]
my.router.name
my.switch.name
my.second.server

[servers]
my.first.server
my.second.server
my.third.server

[computers]
my.computer.name
wife.computer.name

[instances:children]
my.router.name
my.switch.name
my.computer.name
wife.computer.name
my.first.server
my.second.server
my.third.server

In this example, you have defined 7 total devices. They are present in your children section. From there, you can derive different Host Groups. For example here, I have created the hardware, networking, servers, & computers groups.

Let's say you wanted to reboot all of your Personal Computers with your Playbook. Then you would set line 2 to hosts: computers. If you wanted to reboot all of your servers and all of your networking equipment, then you could set it to something like this: hosts: networking:servers

In the event that you wanted all of your devices EXCEPT for my.computer.name to patch & reboot then you could write your Playbook like this:

- hosts: hardware:networking:servers:wife.computer.name
  gather_facts: true
  become: true

  tasks:
    - package:
        name: "*"
        state: latest
      register: patchstatus

    - reboot:
      when: patchstatus is changed

Let me know if this helps or if I missed on your question. Ansible is fun to use so I'm always happy to help when I can.

this will just skip when current hostname is equal to localhost or if your current host is the FQDN of your ansible controller host (basically, the second condition is applicable only if you explicitly defined ansible controller's fqdn in your hosts file)

- name: Patch and reboot
  hosts: all
  gather_facts: true

  tasks:
  - name: Fully patch system
    package:
      name: "*"
      state: latest
    become: true
    register: patchstatus

  - name: Reboot if patched
    reboot:
    become: true
    when: 
      - patchstatus is changed
      - inventory_hostname != 'localhost' or inventory_hostname != 'ansible_controller_fqdn'
Related