Jordan
Jordan

Reputation: 261

Does Ansible delegate_to work with handlers?

I wrote a playbook to modify the IP address of several remote systems. I wrote the playbook to change only a few systems at a time, so I wanted to use delegate_to to change the DNS record on the nameservers as each system was modified, instead of adding a separate play targeted at the nameservers that would change all the host IPs at once.

However, it seems the handler is being run on the primary playbook target, not my delegate_to target. Does anyone have recommendations for working around this?

Here's my playbook:

---
host: hosts-to-modify
serial: 1
tasks:
  - Modify IP for host-to-modify
    //snip//

  - name: Modify DNS entry
    delegate_to: dns-servers
    become: yes
    replace:
    args:
      backup: yes
      regexp: '^{{ inventory_hostname }}\s+IN\s+A\s+[\d\.]+$'
      replace: "{{ inventory_hostname }}   IN    A     {{ new_ip }}"
      dest: /etc/bind/db.my.domain
    notify:
      - reload dns service

handlers:
  - name: reload dns service
    become: yes
    service:
    args:
      name: bind9
      state: reloaded

With an inventory file like the following:

[dns-servers]
ns01
ns02

[hosts-to-modify]
host1 new_ip=10.1.1.10
host2 new_ip=10.1.1.11
host3 new_ip=10.1.1.12
host4 new_ip=10.1.1.13

Output snippet, including error message:

TASK [Modify DNS entry] ********************************************************
Friday 02 September 2016  14:46:09 -0400 (0:00:00.282)       0:00:35.876 ******
changed: [host1 -> ns01]
changed: [host1 -> ns02]

RUNNING HANDLER [reload dns service] *******************************************
Friday 02 September 2016  14:47:00 -0400 (0:00:38.925)       0:01:27.385 ******
fatal: [host1]: FAILED! => {"changed": false, "failed": true, "msg": "no service or tool found for: bind9"}

Upvotes: 3

Views: 3825

Answers (1)

Konstantin Suvorov
Konstantin Suvorov

Reputation: 68269

Yes, Ansible can use delegate_to in handlers, as it is done for a normal task.

Your example playbook syntax is invalid because delegate_to can't be targeted to a group of hosts. If you want to delegate to multiple servers, you should iterate over them.

Here a correct example.

handlers:
  - name: reload dns service
    become: yes
    service:
    args:
      name: bind9
      state: reloaded
    delegate_to: "{{ item }}"
    with_items: "{{ groups['dns-servers'] }}

Upvotes: 7

Related Questions