When running ansible, you may find times that you are looking to have a different host run a task on behalf of your playbooks and this is where delegate_to comes in.

delegate_to can be added as a parameter to tasks allowing for a task in a playbook run to be run on a different host. An example of this would be load balancer rotations. Let's say we have a set of 4 server behind a load balancer which need to be taken out of rotation from the load balancer proactively, maintenance run on that server, and the that server add back into a load balancer. This can be accomplished by added delegate_to a task which removes a server from a load balancer, running the rest of your job, and then adding deletage_to to a subsequent task which then add the server back in.

Below are some more concrete examples of ansible delegate_to in action!

Related Articles

A Simple Example

Let's start really simple. I want to run this playbook command ansible-playbooks -i inventory.yaml -l host_a say_hello.yaml which in essence translates to this:

Run an ansible playbook named say_hello.yaml targeting host_a from inventory.yaml

The playbook will look like this:


- name: Example playbook using delegate_to
  hosts: host_a
  tasks:
    - name: Run command on a different host
      command: echo "Hello from {{ inventory_hostname }}"
      delegate_to: host_b

This is a relatively simple playbook which is boiled down to this:

From the host ansible is being run from, connect to host_a and run a task which writes Hello from host_a and delegate the task to host_b

Under the covers, ansible is connecting to host_a and starting up the playbook up on host_a which then sets up a secondary connection to host_b where the command echo "Hello from {{ inventory_hostname }}" actually gets processed. This allows us to start a playbook up from any host, but then ensure that a specific host always runs specific tasks from the playbook.

Slightly More Complex

In this example, tasks will be interleaved to run on both host_a and host_b as part of the same playbook.


- name: Complex example playbook using delegate_to
  hosts: host_a
  tasks:
    - name: Gather information about the other host
      setup:
        filter: ansible_default_ipv4
      delegate_to: host_b

    - name: Display the IP address of the other host
      debug:
        msg: "The IP address of the other host is {{ ansible_default_ipv4.address }}"

    - name: Run a command on the other host
      command: echo "Hello from {{ inventory_hostname }}"
      delegate_to: host_b

The first task uses delegate_to to send a command to host_b to gather IP Address information. Next a debug statement is written from host_a to show the IP Address information. Finally, host_b then runs the same hello command from the simple example.

Very Complex Example

Here's an example of an Ansible playbook using delegate_to to remove a server from an F5 BigIP load balancers virtual server pool, patch the Linux server, and re-add the server back into the F5 BigIP load balancers virtual server pool:


- name: Example playbook to patch Linux server and readd it back to F5 BigIP
  hosts: localhost
  tasks:
    - name: Remove the server from the F5 BigIP virtual server pool
      bigip_pool_member:
        server: "{{ f5_server }}"
        pool: "{{ f5_pool }}"
        state: absent
      become: yes

    - name: Patch the Linux server
      yum:
        name: "{{ packages }}"
        state: latest
      delegate_to: "{{ patching_host }}"
      become: yes

    - name: Add the server back to the F5 BigIP virtual server pool
      bigip_pool_member:
        server: "{{ f5_server }}"
        pool: "{{ f5_pool }}"
        state: present
      become: yes

The playbook is targeted at the host localhost but the tasks run on different hosts specified in the delegate_to parameter. The first task runs on localhost connecting to the F5 and removes the server from the F5 BigIP virtual server pool. The second task runs on the host specified in patching_host and patches the Linux server. The third task runs on localhost and readds the server back into the F5 BigIP virtual server pool.

If you are looking for further examples of how to utilize ansible delegate_to in your project, you can check out my article about how to provision ESXi virtual machine using ansible.

Conclusion

As you can see, using Ansible's delegate_to functionality can be very powerfully for adding inline functionality to your playbooks by adding task branching to other hosts in your environment.