materna-stackoverflow
materna-stackoverflow

Reputation: 33

Ansible - problem with ansible_facts for packages in jinja template

I try to get all installed packages with Ansible and write them in a "pretty" way to a file.
Calling the module works:

- name: Gather the rpm package facts
  package_facts:
    manager: auto

In a Jinja template I am using a loop, what works too:

{% for item in ansible_facts.packages %}
  {{ item }}
{% endfor %}

Unfortunately the simple output creates this "mess":

    "yum": [
        {
            "arch": "noarch",
            "epoch": null,
            "name": "yum",
            "release": "4.el8",
            "source": "rpm",
            "version": "4.2.23"
        }
    ],

    "zlib": [
        {
            "arch": "x86_64",
            "epoch": null,
            "name": "zlib",
            "release": "16.el8_2",
            "source": "rpm",
            "version": "1.2.11"
        }
    ]

Some of these elements are unnecassry for the current job, so the first call coming in mind was this:

{% for item in ansible_facts.packages %}
  {{ item.name }} {{ item.version }}
{% endfor %}

But this ended just in an error:

fatal: [somehost.example.org]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'unicode object' has no attribute 'name'"}

Searched through the internet, looked into the documentation of Ansible, tried various notations and nothing worked:

vars[item].name  
item[0].name
item["name"]

As last option I tried it with iteritems:

{% for (key,value) in ansible_facts.packages.iteritems() %}
  {{ value }}
{% endfor %}

But this ended I an error to:

fatal: [somehost.example.org]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'list object' has no attribute 'name'"}

It seems I am not smart enough to figure out the solution, can someone lend me a hand?

Sincerely,
a frustrated Ansible user

Upvotes: 3

Views: 476

Answers (1)

seshadri_c
seshadri_c

Reputation: 7340

In the data sample you posted, package name is the key and value is a list of 1 element comprising of a dictionary.

To get the version you have to access the first element. Like so:

{% for key, value in ansible_facts.packages.iteritems() %}
{{ key }} {{ value[0].version }}
{% endfor %}

Should render the file with package list like:

...
zlib 1.2.11
...

Upvotes: 1

Related Questions