Ansible Delegate_to module helps us to execute a specific task in our playbook to run in other host or machine.
This process of handing over the control of execution to another host (or) executing a task in another machine is called as delegation
and the module delegate_to
helps you to configure it properly and achieve the desired result.
While we have already written various playbooks in Devops Junction with delegate_to directive.
This post is going to be dedicated for this directive and to give you a collective example to know everything about this ansible delegate and how to execute a task on other machine or host.
Here are the top three examples published already with delegate_to module in Devops Junction, excluding this one.
- Ansible SSH Key Exchange between hosts
- Ansible update /etc/hosts file across multiple machines
- How to copy files between remote hosts in Ansible
Let us continue to our objective and cover ansible delegate_to from basics.
Ansible delegate_to Example and explanation
As ansible delegate_to
is a directive, not an individual module, It integrates with other modules and it controls the task execution by deciding which host should run the task at runtime.
Refer to the following snapshot of the playbook, there are few tasks.
If you look at the Task3, you can see there is a delegate_to
used to change the control of execution back to the ansible master from the remote host where the task was supposed to run.
this is a simple delegation where the control of execution transferred from remote host to the master.
You can write playbooks to change the control between the remote servers as well. which is already covered in our aforementioned articles. We will take a look in detail shortly.
The Playbook to execute tasks in another host with delegate_to
this is the ansible playbook we have created for this post, to explain the simple delegation between a remote host and the ansible master.
--- - name: "Ansible Delegate_to examples" hosts: testserver tasks: - name: "Task1: start a quick webserver with NC on remote server" shell: "while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; echo Hello from WebServer ; } | nc -l 8081 > /tmp/serverout.log ; done &" #Fire and Forget the job - let it run in background async: 1 poll: 0 - name: "Task2: Enabling the port in firewall" become: true firewalld: port: 8081/tcp permanent: true state: enabled immediate: yes - name: "Task3: Check the status of the remote server from localhost [Ansible master]" uri: url: http://{{inventory_hostname}}:8081 method: GET timeout: 30 status_code: 200 return_content: yes delegate_to: localhost register: webresult - name: "Task4: Printing the website output from the Task3" debug: var=webresult
Execution Output of this playbook
When you are executing this playbook with a single remote host defined under testserver
the output of this playbook would be something like this
Explanation of the playbook
Task1: On the remote server named mwiapp01
defined under hostgroup named testserver
this task would start a quick and simple web server using Netcat command and listen to port 8081.
We have used async and poll of ansible to execute the job and run it background to know more about this refer to our previous article
Task2: On the remote server release the firewall using firewalld
module and enable the port 8081 of our web server, for the public traffic to come in ( in this case, from ansible master)
Task3: Access the web server we have set up using the uri
module. but execute this task on the master server, though the task has been already sent to the remote server mwiapp01
As shown in the following diagram, the task would first be handed over to the remote server and then it will be delegated or re-sent for execution to the master server.
If you look at the playbook output presented earlier, You can see something like this
ok: [mwiapp01 -> localhost]
Unlike other tasks, this task would have two names shown before the status OK.
This indicates that the task has been handed off from mwiapp01 to localhost for execution.
This is how you can understand when a task is delegated_to some other host
Task4: This task is to display the register variable we have used in task3 to save the response content of the URI module. this would display the status code and the content we get as a response when we are accessing our webserver.
In order to cross-verify this, you can use the curl command on the ansible master like this
curl -v http://mwiapp01:8080/
Realtime Example of ansible delegate_to
So far we have talked about how to delegate between a single remote server and a control machine/ansible master. as I mentioned it was very light to start with.
to understand the upcoming playbook and what does it do, it is necessary you read our article on "How to copy files between remote hosts in ansible using delegate_to" and come back here
Hope you read the article we have referred above. so our requirement in that article is to copy files between remote hosts mwiapp01
and mwiapp02
while there were two methods of doing this. the efficient way was using the sync
module and it heavily relies upon delegation
to complete the copy between the hosts.
I am pasting the playbooks from that article here once again
Playbook to copy files from mwiapp01 to 02 using Sync Push
- name: Sync Push task - Executed on source host "{{groups['app'][0]}}" hosts: "{{groups['app'][1]}}" user: wlsusr tasks: - name: Copy the file from mwiapp01 to mwiapp02 using Method Push tags: sync-push synchronize: src: "{{ item }}" dest: "{{ item }}" mode: push delegate_to: “{{groups[‘app’][0]}}“ register: syncfile with_items: - "/tmp/app01-to-app02.jar"
Playbook to copy files from mwiapp01 to 02 using Sync Pull
--- - name: Sync Pull task - Executed on the Destination host "{{groups['app'][1]}}" hosts: "{{groups['app'][0]}}" user: wlsusr tasks: - name: Copy the file from mwiapp01 to mwiapp02 using Method Pull tags: sync-pull synchronize: src: "{{ item }}" dest: "{{ item }}" mode: pull delegate_to: “{{groups[‘app’][1]}}“ register: syncfile run_once: true with_items: - "/tmp/app01-to-app02.jar"
if you look at this playbook you can see that we have a delegate_to
and both of them
In Sync Pull: The execution is handed over/delegated to the destination machine (mwiapp02) from where you are pulling the file from the source
In Sync Push: The execution is handed over/delegated to the source machine (mwiapp01) from there the file gets pushed.
without delegate_to
this would have not been possible.
I hope this clarifies about delegate_to
and as a by-product, you have also learnt some real-time examples on how to copy files between remote hosts, how to update /etc/hosts file on multiple machines etc.
I know this is a little complex to understand. ( or it was once to me when I began ) but when you are reading this slowly and trying it out. You will get the hang of it. I am sure.
If you have any questions/comments about this article. Please let me know in the comments.
Cheers
Sarav
Follow me on Linkedin My Profile Follow DevopsJunction onFacebook orTwitter For more practical videos and tutorials. Subscribe to our channel
Signup for Exclusive "Subscriber-only" Content