Let's test the use-case with 10 remote hosts (test_01 - test_10) in the group test and user my-user in the hosts test_03 and test_07. To test the existence of the user, use the shell command
shell> cat /etc/passwd|grep my-user
For example the playbook
shell> cat playbook.yml
- hosts: test
tasks:
- shell: cat /etc/passwd|grep my-user
register: result
ignore_errors: true
- set_fact:
results: "{{ results|default({})|
combine({item: hostvars[item].result.rc}) }}"
loop: "{{ ansible_play_hosts }}"
run_once: true
- debug:
var: results
run_once: true
gives
ok: [test_01] =>
results:
test_01: 1
test_02: 1
test_03: 0
test_04: 1
test_05: 1
test_06: 1
test_07: 0
test_08: 1
test_09: 1
test_10: 1
To skip the rest of the hosts, when the first host is found, iterate the list of the hosts and test rc. Then add the host to a new group and run the next play with this group. For example,
shell> cat playbook.yml
- hosts: test
vars:
dresult:
rc: 1
tasks:
- block:
- shell: cat /etc/passwd|grep my-user
register: result
loop: "{{ ansible_play_hosts }}"
delegate_to: "{{ item }}"
ignore_errors: true
when: (result|default(dresult)).rc == 1
- set_fact:
my_host: "{{ result.results|json_query('[?rc == `0`].item')|first }}"
- debug:
var: my_host
- add_host:
name: "{{ my_host }}"
groups: my_group
run_once: true
- hosts: my_group
tasks:
- debug:
var: inventory_hostname
gives
shell> ansible-playbook playbook.yml
PLAY [test] ****
TASK [shell] ****
failed: [test_01 -> test_01] (item=test_01) => changed=true
ansible_loop_var: item
cmd: cat /etc/passwd|grep my-user
delta: '0:00:00.023271'
end: '2020-09-25 08:20:31.823168'
item: test_01
msg: non-zero return code
rc: 1
start: '2020-09-25 08:20:31.799897'
stderr: ''
stderr_lines: <omitted>
stdout: ''
stdout_lines: <omitted>
failed: [test_01 -> test_02] (item=test_02) => changed=true
ansible_loop_var: item
cmd: cat /etc/passwd|grep my-user
delta: '0:00:00.017642'
end: '2020-09-25 08:20:33.386657'
item: test_02
msg: non-zero return code
rc: 1
start: '2020-09-25 08:20:33.369015'
stderr: ''
stderr_lines: <omitted>
stdout: ''
stdout_lines: <omitted>
changed: [test_01 -> test_03] => (item=test_03)
skipping: [test_01] => (item=test_04)
skipping: [test_01] => (item=test_05)
skipping: [test_01] => (item=test_06)
skipping: [test_01] => (item=test_07)
skipping: [test_01] => (item=test_08)
skipping: [test_01] => (item=test_09)
skipping: [test_01] => (item=test_10)
...ignoring
TASK [set_fact] ****
ok: [test_01]
TASK [debug] ****
ok: [test_01] =>
my_host: test_03
TASK [add_host] ****
changed: [test_01]
PLAY [my_group] ****
TASK [debug] ****
ok: [test_03] =>
inventory_hostname: test_03
PLAY RECAP *****
test_01: ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
test_03: ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0