ansiblejinja2

How to append strings selectively to looped output of dict2items?


I have the following dictionary structure (I guess it's two dicts nested within one):

machines:
  dev1:
     disks: 4
     user: fred
     NICs: eth0
  dev2:
     disks: 4
     user: joe
     NICs: eth0

I can use the dictionaries to create constructs as follows using looping and dict2items:

- debug:
     msg: "something {{item.value.user}} }}"
  loop: "{{ machines | dict2items }}"

This would output:

ok: =>
  msg: something fred
ok: =>
  msg: something joe

Sometimes, however, I need to change certain specific dict values on the fly by suffixing text. I may want the output from dict1 to change from something fred to something fred-somebody, BUT I would not want that same suffix, -somebody, to be applied to the user for dict2 (otherwise I guess I could do this: msg: "something {{item.value.user}}-string }}").

I'm wondering whether this can be done via applying certain filters to the loop? Any other thoughts?


Solution

  • Q: "How to append strings selectively to looped output of dict2items? ... wondering whether this can be done via applying certain filters to the loop? Any other thoughts?"

    For a structured and generic solution approach one option would be to use Jinja2 Templating and one may also have a look into proper way to concatenate variable strings.

    A minimal example playbook

    ---
    - hosts: localhost
      become: false
      gather_facts: false
    
      vars:
    
        machines:
          dev1:
            disks: 4
            user: fred
            NICs: eth0
          dev2:
            disks: 4
            user: joe
            NICs: eth0
    
        prefix: 'something'
        suffix: 'somebody'
    
        has_suffix:
          dev1: true
          dev2: false
    
      tasks:
    
        - debug:
            msg: "{{ prefix ~ ' ' ~ item.value.user ~ '-' ~ suffix }}"
          loop: "{{ machines | dict2items }}"
    
        - debug:
            msg: |
              {% for dev in (machines | dict2items) %}
              {{ has_suffix[dev.key] }}
              {% endfor %}
    
        - debug:
            msg: |
              {% for dev in (machines | dict2items) %}
              {% if has_suffix[dev.key] %}
              {{ prefix ~ ' ' ~ dev.value.user ~ '-' ~ suffix }}
              {% else %}
              {{ prefix ~ ' ' ~ dev.value.user }}
              {% endif %}
              {% endfor %}
    

    will result into an output of

    TASK [debug] **************************************************************************************
    ok: [localhost] => (item={'key': 'dev1', 'value': {'disks': 4, 'user': 'fred', 'NICs': 'eth0'}}) =>
      msg: something fred-somebody
    ok: [localhost] => (item={'key': 'dev2', 'value': {'disks': 4, 'user': 'joe', 'NICs': 'eth0'}}) =>
      msg: something joe-somebody
    
    TASK [debug] **************************************************************************************
    ok: [localhost] =>
      msg: |-
        True
        False
    
    TASK [debug] **************************************************************************************
    ok: [localhost] =>
      msg: |-
        something fred-somebody
        something joe