<p>Let's test the use-case with 10 remote hosts (test_01 - test_10) in the group <em>test</em> and user <em>my-user</em> in the hosts test_03 and test_07. To test the existence of the user, use the shell command</p>
<pre class="lang-sh prettyprint-override"><code>shell&gt; cat /etc/passwd|grep my-user
</code></pre>
<p>For example the playbook</p>
<pre class="lang-yaml prettyprint-override"><code>shell&gt; cat playbook.yml
- hosts: test
  tasks:
    - shell: cat /etc/passwd|grep my-user
      register: result
      ignore_errors: true
    - set_fact:
        results: &quot;{{ results|default({})|
                     combine({item: hostvars[item].result.rc}) }}&quot;
      loop: &quot;{{ ansible_play_hosts }}&quot;
      run_once: true
    - debug:
        var: results
      run_once: true
</code></pre>
<p>gives</p>
<pre class="lang-yaml prettyprint-override"><code>ok: [test_01] =&gt; 
  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
</code></pre>
<hr>
<p>To skip the rest of the hosts, when the first host is found, iterate the list of the hosts and test <em>rc</em>. Then add the host to a new group and run the next play with this group. For example,</p>
<pre class="lang-yaml prettyprint-override"><code>shell&gt; cat playbook.yml
- hosts: test
  vars:
    dresult:
      rc: 1
  tasks:
    - block:
        - shell: cat /etc/passwd|grep my-user
          register: result
          loop: &quot;{{ ansible_play_hosts }}&quot;
          delegate_to: &quot;{{ item }}&quot;
          ignore_errors: true
          when: (result|default(dresult)).rc == 1
        - set_fact:
            my_host: &quot;{{ result.results|json_query('[?rc == `0`].item')|first }}&quot;
        - debug:
            var: my_host
        - add_host:
            name: &quot;{{ my_host }}&quot;
            groups: my_group
      run_once: true


- hosts: my_group
  tasks:
    - debug:
        var: inventory_hostname
</code></pre>
<p>gives</p>
<pre class="lang-yaml prettyprint-override"><code>shell&gt; ansible-playbook playbook.yml 

PLAY [test] ****

TASK [shell] ****
failed: [test_01 -&gt; test_01] (item=test_01) =&gt; 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: &lt;omitted&gt;
  stdout: ''
  stdout_lines: &lt;omitted&gt;
failed: [test_01 -&gt; test_02] (item=test_02) =&gt; 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: &lt;omitted&gt;
  stdout: ''
  stdout_lines: &lt;omitted&gt;
changed: [test_01 -&gt; test_03] =&gt; (item=test_03)
skipping: [test_01] =&gt; (item=test_04) 
skipping: [test_01] =&gt; (item=test_05) 
skipping: [test_01] =&gt; (item=test_06) 
skipping: [test_01] =&gt; (item=test_07) 
skipping: [test_01] =&gt; (item=test_08) 
skipping: [test_01] =&gt; (item=test_09) 
skipping: [test_01] =&gt; (item=test_10) 
...ignoring

TASK [set_fact] ****
ok: [test_01]

TASK [debug] ****
ok: [test_01] =&gt; 
  my_host: test_03

TASK [add_host] ****
changed: [test_01]

PLAY [my_group] ****

TASK [debug] ****
ok: [test_03] =&gt; 
  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
</code></pre>

CC BY-SA 4.0
2020-09-25T06:31:29.117Z
2020-09-25T07:26:36.810Z
2020-09-25T07:26:36.810Z
Vladimir Botka
<p>I have a list of hosts using aws_ec2 and I want to find the first host where the ec2 instance has a specific docker container.</p>
<p>I created a play book with a list of tasks, which ultimately executes a curl command.  I only want to execute it on one host but first I have to find that host based on if the host is running a specific docker image.  I'm using a shell task to execute <code>docker ps | grep my-filter</code> to see if the host has the docker container named &quot;my-filter&quot;, once that container is found on that particular host, I'd like to execute the rest of my tasks on that particular host.</p>
<p>I was looking at with_first_found but that seems to only apply to files.</p>
<p>Any help/pointers would be appreciated.</p>

<ansible>
How to skip rest of hosts when item found in host - Ansible
Will Huang
# How to skip rest of hosts when item found in host - Ansible

(Asked by: username_0 on 2020-09-25)

I have a list of hosts using aws\_ec2 and I want to find the first host where the ec2 instance has a specific docker container.

I created a play book with a list of tasks, which ultimately executes a curl command. I only want to execute it on one host but first I have to find that host based on if the host is running a specific docker image. I'm using a shell task to execute `docker ps | grep my-filter` to see if the host has the docker container named "my-filter", once that container is found on that particular host, I'd like to execute the rest of my tasks on that particular host.

I was looking at with\_first\_found but that seems to only apply to files.

Any help/pointers would be appreciated.

**Tags:** ansible


---

## 1 answers

### Answer by username_1 on 2020-09-25. Score: 2 | Accepted answer

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: 
  stdout: ''
  stdout_lines: 
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: 
  stdout: ''
  stdout_lines: 
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


---

