# Failed host list from 'rescue' task

**URL:** <https://forum.ansible.com/t/failed-host-list-from-rescue-task/37774>\
**Category:** Ansible Project\
**Created:** [March 15, 2023, 5:44pm UTC](https://forum.ansible.com/t/failed-host-list-from-rescue-task/37774 "2023-03-15T17:44:55Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![AharonuReddy](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/aharonureddy/32/5464_2.png) [@AharonuReddy](https://forum.ansible.com/u/AharonuReddy)\
**Post date:** [March 15, 2023, 5:44pm UTC](https://forum.ansible.com/t/failed-host-list-from-rescue-task/37774/1 "2023-03-15T17:44:55Z")

</div>

Hello Everyone,

Greetings!

I am working to get failed hosts from ‘rescue’ section into a CSV file.

When i run task for **'inventory\_hostname** ’ from **‘rescue’** section:

> rescue:
> 
> - name: inventory\_host name list debug  
> debug:  
> msg: “{{ inventory\_hostname }}”  
> Output:
> 
> TASK [inventory\_host name list debug] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
> ok: [bogus1] =\> {}
> 
> MSG:
> 
> bogus1  
> ok: [bogus2] =\> {}
> 
> MSG:
> 
> bogus2

**when i tried to append data to a list.**

> - set\_fact:  
> failed\_list: “{{ failed\_list + [ansible\_host] }}”
> - name: failed\_list debug  
> debug: var=failed\_list

Output:

TASK [set\_fact] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [bogus1]  
ok: [bogus2]

TASK [failed\_list debug] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [bogus1] =\> {  
“failed\_list”: [  
“bogus1”  
]  
}  
ok: [bogus2] =\> {  
“failed\_list”: [  
“bogus2”  
]  
}

Here bogus1, bogus2 host names are failed in ‘resce’ section.  
We have multiple hosts in our environment. While running playbook we have to capture failed hostname into a file as mentioned below:

**failed\_hosts.csv:**  
**number of failed hots: 2**  
**hostname:**  
**bogus1**  
**bogus2**

Thank you for your help.

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [March 15, 2023, 6:43pm UTC](https://forum.ansible.com/t/failed-host-list-from-rescue-task/37774/2 "2023-03-15T18:43:06Z")

</div>

Study and play around with these expressions until you understand what each piece does.  
set\_fact sets a host-specific fact, which for convenience can be accessed like any other variable.  
Any host can see other hosts’ facts/variables by looking in hostvars[‘somehost’]._varname_.  
The “CSV” is really just a list of failed hosts. With only one column, does CSV really mean anything?  
The final copy task should be a template task, but I left it in-line for clarity.

```auto
  - name: Update failed_list fact
    ansible.builtin.set_fact:
      failed_list: "{{ failed_list | default([]) + [ansible_host] }}"

  - name: Debug list
    ansible.builtin.debug:
     msg:
      - "by play_hosts: {{ ansible_play_hosts | map('extract', hostvars) | map(attribute='failed_list') | flatten }}"
      - "by all: {{ hostvars | dict2items | map(attribute='value') | map(attribute='failed_list', default=[]) | flatten }}"

  - name: Create failed_list CSV
    ansible.builtin.copy:
      content: |
        failed
        {% for host in hostvars | dict2items | map(attribute='value') | map(attribute='failed_list', default=[]) | flatten %}
        {{ host }}
        {% endfor %}
      dest: /tmp/failed_list.csv
    run_once: true

```

Hope this helps.

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [March 15, 2023, 11:47pm UTC](https://forum.ansible.com/t/failed-host-list-from-rescue-task/37774/3 "2023-03-15T23:47:53Z")

</div>

> I am working to get failed hosts from 'rescue' section into a CSV file.  
> [...]  
> \> \*when i tried to append data to a list. \*
> 
> \> - set\_fact:  
> \> failed\_list: "{{ failed\_list + [ansible\_host] }}"
> 
> \*failed\_hosts.csv:\*  
> \*number of failed hots: 2\*  
> \*hostname:\*  
> \*bogus1\*  
> \*bogus2\*

Each host will have its own variable \*failed\_list\*. Therefore, it  
makes no sense to record \*ansible\_host\* in this list. Instead, you  
might want to record the failed tasks. For example, the block below  
runs three tasks. If any of the tasks fails the name of it will be  
added to the list \*failed\_list\*

&nbsp;&nbsp;&nbsp;&nbsp;- name: block A  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- name: task1A  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;command: "{{ ['true', 'false']|random }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- name: task2A  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;command: "{{ ['true', 'false']|random }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- name: task3A  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;command: "{{ ['true', 'false']|random }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rescue:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- set\_fact:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;failed\_list: "{{ failed\_list +  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ansible\_failed\_task.name] }}"

Create dictionary of all hosts and failed tasks

&nbsp;&nbsp;failed\_lists: "{{ dict(groups.all|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zip(hostvars|dict2items|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map(attribute='value.failed\_list',  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default=))) }}"

For example, given the inventory

&nbsp;&nbsp;\> cat hosts  
&nbsp;&nbsp;host\_A ansible\_host=10.1.0.61  
&nbsp;&nbsp;host\_B ansible\_host=10.1.0.62  
&nbsp;&nbsp;host\_C ansible\_host=10.1.0.63

a play running two blocks (A and B) on two hosts (host\_A and host\_C)  
gives

&nbsp;&nbsp;failed\_lists:  
&nbsp;&nbsp;&nbsp;&nbsp;host\_A: [task1A, task1B]  
&nbsp;&nbsp;&nbsp;&nbsp;host\_B:   
&nbsp;&nbsp;&nbsp;&nbsp;host\_C: [task3A, task2B]

Declare the list of failed hosts by selecting nonempty lists

&nbsp;&nbsp;failed\_hosts: "{{ failed\_lists|dict2items|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selectattr('value')|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map(attribute='key')|list }}"

gives

&nbsp;&nbsp;failed\_hosts: [host\_A, host\_C]

Now you can create reports. For example, to write the file on the  
controller, delegate the task to localhost

&nbsp;&nbsp;&nbsp;&nbsp;- copy:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dest: /tmp/failed\_hosts.yaml  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;content: |  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;number\_of\_failed\_hosts: {{ failed\_hosts|length }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hostnames: {{ failed\_hosts|join(', ') }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% for h,l in failed\_lists.items() %}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ h }}: {{ l|sort|join(', ') }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% endfor %}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delegate\_to: localhost  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;run\_once: true

gives the YAML file

&nbsp;&nbsp;\> cat /tmp/failed\_hosts.yaml  
&nbsp;&nbsp;number\_of\_failed\_hosts: 2  
&nbsp;&nbsp;hostnames: host\_A, host\_C  
&nbsp;&nbsp;host\_A: task1A, task1B  
&nbsp;&nbsp;host\_B:  
&nbsp;&nbsp;host\_C: task2B, task3A

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
Example of a complete playbook for testing

---

<div class="post-metadata">

**Author:** ![AharonuReddy](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/aharonureddy/32/5464_2.png) [@AharonuReddy](https://forum.ansible.com/u/AharonuReddy)\
**Post date:** [March 16, 2023, 1:38pm UTC](https://forum.ansible.com/t/failed-host-list-from-rescue-task/37774/4 "2023-03-16T13:38:39Z")

</div>

Hi Todd,

Greetings!

Thank you for your time and help. It is tested for my playbook and also It is very helpful and I am exploring it.

The below one is not successful as it got error 'The task includes an option with an defined variable. The error was: ‘ansible.vars.hostvars.HostVarsVars object’ has no attribute ‘failed\_host’ ’

```auto
- "by play_hosts: {{ ansible_play_hosts | map('extract', hostvars)

```

Yes, I got the expected results ans added my other requirements to csv data.

Once again thank you.

---

<div class="post-metadata">

**Author:** ![AharonuReddy](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/aharonureddy/32/5464_2.png) [@AharonuReddy](https://forum.ansible.com/u/AharonuReddy)\
**Post date:** [March 17, 2023, 5:39am UTC](https://forum.ansible.com/t/failed-host-list-from-rescue-task/37774/5 "2023-03-17T05:39:37Z")

</div>

```auto
I am digging into ansible.builtin.copy and ansible.builtin.template **content** but not get options to append.

```

Can we append two different tasks data into one csv file instead of over write?

One task i have under ‘ **rescue** ’ section as example below:

```auto
rescue:
- name: Create failed_list CSV
  **ansible.builtin.copy:**
      **content: |**
        failed
        {% for host in hostvars | dict2items | map(attribute='value') | map(attribute='failed_list', default=[]) | flatten %}
        {{ host }}
        {% endfor %}
      dest: **/tmp/facts.csv**
    run_once: true

```

```auto
/tmp/facts.csv gives

```

```auto
# cat /tmp/facts.csv
somedata1
somedata2

```

```auto
 I have another task cvs data under ' **always**' section:

always:
- name: append volume info to CSV
  **ansible.builtin.copy:**
      **content: |**
        failed
        {% example rule %}
        {{ host }}
        {% endfor %}
      dest: /tmp/facts.csv
    run_once: true

Gives:

```

```auto
# cat /tmp/facts.csv
somedata3

```

```auto
somedata4 

```

It should append data instead of overwrite here. Is it possible?  
We just need end of two files data into one:

```auto
# cat /tmp/facts.csv
somedata1
somedata2
somedata3
somedata4

```

```auto
Thank you,

```

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [March 17, 2023, 12:06pm UTC](https://forum.ansible.com/t/failed-host-list-from-rescue-task/37774/6 "2023-03-17T12:06:31Z")

</div>

Consider [https://docs.ansible.com/ansible/latest/collections/ansible/builtin/assemble\_module.html](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/assemble_module.html)

It combines multiple files into one.

---

<div class="post-metadata">

**Author:** ![AharonuReddy](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/aharonureddy/32/5464_2.png) [@AharonuReddy](https://forum.ansible.com/u/AharonuReddy)\
**Post date:** [March 17, 2023, 1:43pm UTC](https://forum.ansible.com/t/failed-host-list-from-rescue-task/37774/7 "2023-03-17T13:43:06Z")

</div>

Greetings for the day!

Looks like ansible.builtin.assemble for two different files from directory to another required file.

Sorry to raise my query again but…wanted to be clear.

My requirement is, **As i mentioned in previous mail** : playbook should be having only one csv file but two different tasks using that.( not to store 2 diff files and combine). It is to append one file from 2 tasks.

```auto
**# cat /tmp/facts.csv**
somedata1 [coming from 'rescue' task
somedata2 [coming from 'rescue' task 
somedata3 [ coming from 'always' task
somedata4 [coming from 'always' task

```

Thank you,

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [March 17, 2023, 3:35pm UTC](https://forum.ansible.com/t/failed-host-list-from-rescue-task/37774/8 "2023-03-17T15:35:12Z")

</div>

Right, but as you’ve discovered `copy` and `template` won’t update part of a file.  
So your two choices are: (1) remove the various template/copy tasks from the various places in your playbook and replace them with a single task at the end that creates the single file, or (2) store the output of the various tasks to separate files and use `assemble` (or a shell script) at then end to put the disparate pieces into one file.  
If there are other options, they aren’t obvious to me at the moment.

---

<div class="post-metadata">

**Author:** ![AharonuReddy](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/aharonureddy/32/5464_2.png) [@AharonuReddy](https://forum.ansible.com/u/AharonuReddy)\
**Post date:** [March 17, 2023, 4:18pm UTC](https://forum.ansible.com/t/failed-host-list-from-rescue-task/37774/9 "2023-03-17T16:18:32Z")

</div>

Thanks Todd.

I will give a try option 1.

**(1) remove the various template/copy tasks from the various places in your playbook and replace them with a single task at the end that creates the single file, or** (2) store the output of the various tasks to separate files and use `assemble` (or a shell script) at then end to put the disparate pieces into one file.
