display information returned with debug in a more usable layout

I am trying to retreive information about installed versions of a package on a couple of hosts.

  • name: check pgBackRest version
    command: /usr/bin/pgbackrest version
    register: backrest_version

  • name: Print return information from the previous task
    ansible.builtin.debug:
    var: backrest_version

the output I am getting is already contains the information wanted but is not sufficiently handy format-wise.especially running on more then a handfull of hosts.

TASK [Print return information from the previous task] ***********************************************************************
ok: [step-0227] => {
“backrest_version”: {
“changed”: true,
“cmd”: [
“/usr/bin/pgbackrest”,
“version”
],
“delta”: “0:00:00.008057”,
“end”: “2022-07-18 18:08:20.394231”,
“failed”: false,
“msg”: “”,
“rc”: 0,
“start”: “2022-07-18 18:08:20.386174”,
“stderr”: “”,
“stderr_lines”: ,
“stdout”: “pgBackRest 2.39”,
“stdout_lines”: [
pgBackRest 2.39
]
}
}

To make this more scalable I am wondering to how to tweak this further so I can get a more usable kind of list or csv with only the concrete information needed like domainname & the version of my package in question. So what would be the direction to investigat in order to move towards the happyplace in this endeavour?

     ok: [step-0227] => {
     "backrest_version": {
      ...
     "stdout": "pgBackRest 2.39",

... get a more usable kind of list or csv with ... domainname & the
version of my package in question.

Get versions and create dictionary *pkg*

  ver: "{{ ansible_play_hosts|
           map('extract', hostvars, ['backrest_version', 'stdout'])|
           map('split', ' ')|map('last')|
           list }}"
  pkg: "{{ dict(ansible_play_hosts|zip(ver)) }}"

For example, given the data

  ok: [test_11] =>
    backrest_version.stdout: pgBackRest 2.39
  ok: [test_12] =>
    backrest_version.stdout: pgBackRest 2.40
  ok: [test_13] =>
    backrest_version.stdout: pgBackRest 2.41

you get the dictionary

  pkg:
    test_11: '2.39'
    test_12: '2.40'
    test_13: '2.41'

Write the CSV file

    - copy:
        dest: pkg.csv
        content: |-
          {% for k,v in pkg.items() %}
          {{ k }},{{ v }}
          {% endfor %}
      delegate_to: localhost
      run_once: true

You get

  > cat pkg.csv
  test_11,2.39
  test_12,2.40
  test_13,2.41

thx for the suggestions. I am sure they are grant, but I seem not to be at level to put them to work correctly yet.
So, would you mind to specify how to utilize those lines successfully?

my interpretation looked like this:

######### playbook #########################################
- hosts: all
  vars:
    ansible_user: gwagner

  tasks:
    - name: check pgBackRest version
      ansible.builtin.command: /usr/bin/pgbackrest version
      register: backrest_version

    - name: Print return information from the previous task
      ansible.builtin.debug:
        var: backrest_version

    - name: Get versions and create dictionary *pkg*
      ver: "{{ ansible_play_hosts | map('extract', hostvars, ['backrest_version', 'stdout']) | map('split', ' ') | map('last') | list }}"
      pkg: "{{ dict(ansible_play_hosts|zip(ver)) }}"

    - name: Write the CSV file
      copy:
        dest: pkg.csv
        content: |-
          {% for k,v in pkg.items() %}
          {{ k }},{{ v }}
          {% endfor %}
      delegate_to: localhost
      run_once: true

You're welcome. Put the declarations of *ver* and *pkg* into the
*vars*. I edited your code in-line

thnks, that worked (of course).

I try not to be embarrased too much for having someone spelling this outfor me like this :-).
Hopefully I'll be able to pay back to this list later down the road.

I see there is a lot to learn and understand yet (in this case "use of variables" for example).

I see there is a lot to learn and understand yet (in this case "use
of variables" for example).

> > - hosts: all
> > vars:
> > ansible_user: gwagner
> > ver: "{{ ansible_play_hosts|
> > map('extract', hostvars, ['backrest_version', 'stdout'])|
> > map('split', ' ')|map('last')|
> > list }}"
> > pkg: "{{ dict(ansible_play_hosts|zip(ver)) }}"
> >
> > tasks:
> > - name: check pgBackRest version
> > ansible.builtin.command: /usr/bin/pgbackrest version
> > register: backrest_version
> >
> > - name: Print return information from the previous task
> > ansible.builtin.debug:
> > var: backrest_version.stdout
> > when: debug|d(false)|bool
> >
> > - name: Write the CSV file
> > ansible.builtin.copy:
> > dest: pkg.csv
> > content: |-
> > {% for k,v in pkg.items() %}
> > {{ k }},{{ v }}
> > {% endfor %}
> > delegate_to: localhost
> > run_once: true

There are a couple of aspects.

* It's good to know that in Ansible the variables are evaluated at
  the last moment, aka "lazy evaluation".

* There are many places where you can declare variables. See
  https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable

* Where would you like to use the variables? In your case, this is
  probably the best question to ask when you want to decide where to
  declare the variables. Put them into the playbook vars (above) if
  you want to use them in the whole playbook. If you need the
  variables to write the CSV file only put them into the task vars
  (below)

  - name: Write the CSV file
    ansible.builtin.copy:
      dest: pkg.csv
      content: |-
        {% for k,v in pkg.items() %}
        {{ k }},{{ v }}
        {% endfor %}
    delegate_to: localhost
    run_once: true
    vars:
      ver: "{{ ansible_play_hosts|
               map('extract', hostvars,
               ['backrest_version','stdout'])|map('split', ' ')|
               map('last')|
              list }}"
      pkg: "{{ dict(ansible_play_hosts|zip(ver)) }}"

  This limits the scope of the variables. See
  https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#scoping-variables

* To make the code cleaner, you can put the variables into some files.
  For example into the group_vars,

  > cat group_vars/all
  ansible_user: gwagner
  ver: "{{ ansible_play_hosts|
           map('extract', hostvars, ['backrest_version', 'stdout'])|
           map('split', ' ')|map('last')|
           list }}"
  pkg: "{{ dict(ansible_play_hosts|zip(ver)) }}"
  content: |-
    {% for k,v in pkg.items() %}
    {{ k }},{{ v }}
    {% endfor %}

  This will simplify the playbook

  - hosts: all
    tasks:
      - name: check pgBackRest version
        ansible.builtin.command: /usr/bin/pgbackrest version
        register: backrest_version
      - name: Write the CSV file
        ansible.builtin.copy:
          dest: pkg.csv
          content: "{{ content }}"
        delegate_to: localhost
        run_once: true