On Wed, 15 Mar 2023 17:44:55 +0000 Aharonu <[email protected]> wrote:
> 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*
- name: block A
block:
- name: task1A
command: "{{ ['true', 'false']|random }}"
- name: task2A
command: "{{ ['true', 'false']|random }}"
- name: task3A
command: "{{ ['true', 'false']|random }}"
rescue:
- set_fact:
failed_list: "{{ failed_list +
[ansible_failed_task.name] }}"
Create dictionary of all hosts and failed tasks
failed_lists: "{{ dict(groups.all|
zip(hostvars|dict2items|
map(attribute='value.failed_list',
default=[]))) }}"
For example, given the inventory
shell> cat hosts
host_A ansible_host=10.1.0.61
host_B ansible_host=10.1.0.62
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
failed_lists:
host_A: [task1A, task1B]
host_B: []
host_C: [task3A, task2B]
Declare the list of failed hosts by selecting nonempty lists
failed_hosts: "{{ failed_lists|dict2items|
selectattr('value')|
map(attribute='key')|list }}"
gives
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
- copy:
dest: /tmp/failed_hosts.yaml
content: |
number_of_failed_hosts: {{ failed_hosts|length }}
hostnames: {{ failed_hosts|join(', ') }}
{% for h,l in failed_lists.items() %}
{{ h }}: {{ l|sort|join(', ') }}
{% endfor %}
delegate_to: localhost
run_once: true
gives the YAML file
shell> cat /tmp/failed_hosts.yaml
number_of_failed_hosts: 2
hostnames: host_A, host_C
host_A: task1A, task1B
host_B:
host_C: task2B, task3A
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Example of a complete playbook for testing
---
- hosts: host_A,host_C
vars:
failed_list: []
failed_lists: "{{ dict(groups.all|
zip(hostvars|dict2items|
map(attribute='value.failed_list',
default=[]))) }}"
failed_hosts: "{{ failed_lists|dict2items|
selectattr('value')|
map(attribute='key')|list }}"
tasks:
- name: block A
block:
- name: task1A
command: "{{ ['true', 'false']|random }}"
- name: task2A
command: "{{ ['true', 'false']|random }}"
- name: task3A
command: "{{ ['true', 'false']|random }}"
rescue:
- set_fact:
failed_list: "{{ failed_list +
[ansible_failed_task.name] }}"
- name: block B
block:
- name: task1B
command: "{{ ['true', 'false']|random }}"
- name: task2B
command: "{{ ['true', 'false']|random }}"
- name: task3B
command: "{{ ['true', 'false']|random }}"
rescue:
- set_fact:
failed_list: "{{ failed_list +
[ansible_failed_task.name] }}"
- block:
- debug:
var: failed_lists|to_yaml
- debug:
var: failed_hosts|to_yaml
run_once: true
- copy:
dest: /tmp/failed_hosts.yaml
content: |
number_of_failed_hosts: {{ failed_hosts|length }}
hostnames: {{ failed_hosts|join(', ') }}
{% for h,l in failed_lists.items() %}
{{ h }}: {{ l|sort|join(', ') }}
{% endfor %}
delegate_to: localhost
run_once: true
- block:
- include_vars:
file: /tmp/failed_hosts.yaml
name: test
- debug:
var: test
run_once: true
...
--
Vladimir Botka
--
You received this message because you are subscribed to the Google Groups
"Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/ansible-project/20230316002416.11d4a3c7%40gmail.com.
pgpWv9i4PU0yT.pgp
Description: OpenPGP digital signature
