I'm trying to make a report with installed packages and their version from a couple of machines.
The report must be created on the machine from where the playbook is executed.
Here is my current playbook
---
- name: main
hosts: all
gather_facts: no
become: true
tasks:
- setup:
gather_subset:
- '!all'
- name: Gather rpm packages
package_facts:
manager: auto
ignore_errors: true
- name: Create the result file
local_action:
module: copy
content: |
{% for h in groups.all %}
{{h}}; OS: {{hostvars[h]['ansible_distribution']|default('N/A')}}; Release: {{hostvars[h]['ansible_distribution_version']|default('N/A')}}
List of instaled packages:.......
#==============================================
{% for k,v in hostvars[h].ansible_facts.packages.iteritems() %}
package {{ k.rjust(24) }} version {{ v[0].version }}
{%endfor%}
#==============================================
{%endfor%}
dest: '/reports/OS_info.txt'
Which is run with
ansible-playbook -i rh_inventory -u ansuser02 os_extract_info.yml
Now, if all hosts are reachable, the report is created, however, if one or more hosts are unreachable the playbook execution fails with:
fatal: [INFRA-116]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'packages'
And I can't figure out what could be the best approach to overcome this issue.
You have to apply a default
filter to that fact, as you did for the other information:
hostvars[h].ansible_distribution | default('N/A')
In this case, since you want to loop over the key / value pair of a dictionary, you can default the packages
fact to any empty one:
{% for k, v in (hostvars[h].packages | default({})).items() %}