There is no such integrated mechanism that I know of. The task will start with the first host in the inventory depending on what is matched in your play (i.e. the hosts
parameter) and eventually the limits you used on your command line (i.e. the -l
option to ansible playbook) and will stop after this one if run_once
was used.
Meanwhile, I think there is a way to meet your target.
Background info
- Ansible maintains some magic variable among which:
ansible_play_hosts
- the list of active hosts in the current play run limited by the serial, aka ‘batch’
hostvars
- a hashmap with all the hosts in inventory and variables assigned to them
- The available memory on each host is available in
ansible_memfree_mb
. This var only exist if you gather facts on your hosts (i.e. you did not turn this off with gather_facts: no
on your play)
- The solution uses two filters for which you may want to have a deeper look
map
allows us to extract only the relevant host info from hostvars
json_query
(implementing jmespath
) allows us to filter the list of vars looking for max memory and getting only the hostname of the relevant node at final
Proposed solution
The below playbook demonstrate how to combine the above elements to hit the target. The task uses a combination of run_once
, delegate_to
and delegate_facts
so that it runs on a specific host as if it as been chosen in first place.
---
- name: Delegate single running task to dynamically chosen host
hosts: all
gather_facts: true
vars:
max_mem_query: max_by(@, &ansible_memfree_mb).inventory_hostname
selected_host: >-
{{
ansible_play_hosts |
map('extract', hostvars) |
list |
json_query(max_mem_query)
}}
tasks:
- name: Run a command on host with most memory
debug:
msg: "I would run on host {{ inventory_hostname }}"
run_once: true
delegate_to: "{{ selected_host }}"
delegate_facts: true
Note: I only tested this against an inventory with two local docker instances to validate my playbook so the output is not really relevant (all instances have the same available memory, the first one is chosen which happens to delegate to itself). But I'm quite confident it will work and I'm ready to edit this to accommodate with some eventual quirks if not.