Save part of a result in Ansible using register, set_fact, or filter

Viewed 262

Is it possible to register, set_fact, or filter the result of Ansible modules to store a single value?

In the example below, stat returns a large object containing numerous values but I only care about the checksum. I want to save just the checksum so that I do not have to index into the full stat object every time I want to access the checksum.

- name: register checksum | grub file (/etc/default/grub)
  stat:
    path: /etc/default/grub
    checksum_algorithm: sha1
  register: grub_checksum

# DESIRED
- debug:
    msg: "{{ grub_checksum }}" 
    # "checksum": "2ef73284108f87e303c56e74aa7bc14838646cf2"

# WORKS (but requires indexing into larger stat object when I only care about checksum)
- debug:
    msg: "{{ grub_checksum.stat.checksum }}" 
    # "checksum": "2ef73284108f87e303c56e74aa7bc14838646cf2"

How can this be accomplished?

2 Answers

You should be able to use ansible "set_fact" with a Jinja expression for the fact to extract that part in a separate task.

Something like:

- name: Extract interesting part
  set_fact:
    name_for_interesting_part: "{{ the_registered_result.interesting.part }}"

According the module documentation, the Return Values are a

Dictionary containing all the stat data, some platforms might add additional fields.

According the module Parameters it is possible to control parts of the gathering and output. One could try to set additionally

- name: register checksum | grub file (/etc/default/grub)
  stat:
    path: /etc/default/grub
    checksum_algorithm: sha1
    get_attributes: false
    get_mime: false
  register: grub_checksum

however, this might be still more data and information than the request for a single value checksum.

In respect of your initial request

... stat returns a large object containing numerous values but I only care about the checksum. I want to save just the checksum ...

and since the stat module has already the ability for information gathering control, you may have a look into the source ansible/lib/ansible/modules/stat.py .

It might be possible for you to

  • either enhance, extend or customize the module with an option get_values: false or checksum_only: true,
  • or create a custom module checksum.py where you have removed all for you unnecessary code parts and only get back the checksum as single value.

To do so look at the code starting from lines with if get_* and the default output = dict(...). A (quick) stripped down version of the module with checksum option only could produce an output like

TASK [Show result] **************************************
ok: [localhost] =>
  msg:
    changed: false
    failed: false
    stat:
      block_size: 4096
      blocks: 8
      checksum: 0123456789012345678901234567890123456789
      device_type: 0
      isreg: true
      readable: true

A third option could be to use the shell module to Register the checksum as single result.

- name: register checksum | grub file (/etc/default/grub)
  shell:
    cmd: sha1sum /etc/default/grub | cut -d " " -f 1
  register: grub_checksum

However, any option will still provide some more values than the requested

TASK [Show result] **********************************
ok: [localhost] =>
  msg:
    changed: true
    cmd: sha1sum /etc/default/grub | cut -d " " -f 1
    delta: '0:00:00.183056'
    end: '2022-03-04 10:00:00.043252'
    failed: false
    rc: 0
    start: '2022-03-04 10:00:00.860196'
    stderr: ''
    stderr_lines: []
    stdout: 0123456789012345678901234567890123456789
    stdout_lines:
    - 0123456789012345678901234567890123456789

because every module has common Return Values.

Further Reading

Related