2

I wanted to update the list with ansible which contains dictionary items based on certain conditions

for example:

list1:
  - {"name": "test1", "uid": 100, "gid": 250}
  - {"name": "test2", "uid": 101, "gid": 250}
  - {"name": "test3", "uid": 103, "gid": 250}
  - {"name": "test4", "uid": 104, "gid": 250}

list2: [100, 101]

list3: [102,103]

if uid match with an item in list2 it will change gid=300 and if match with list3 it updates it as 400, the rest items remain the same in the list1

Please suggest how I could generate the list1 with the above conditions

Sandeep
  • 23
  • 1
  • 4

1 Answers1

3

For example

    - set_fact:
        l4: "{{ l4|d([]) + [item|combine({'gid': _gid|from_yaml})] }}"
      loop: "{{ list1 }}"
      vars:
        _gid: |
          {% if item.uid in list2 %}
          300
          {% elif item.uid in list3 %}
          400
          {% else %}
          {{ item.gid }}
          {% endif %}

gives

  l4|to_yaml: |-
    - {gid: 300, name: test1, uid: 100}
    - {gid: 300, name: test2, uid: 101}
    - {gid: 400, name: test3, uid: 103}
    - {gid: 250, name: test4, uid: 104}

Update

It's not necessary to iterate the list in Ansible 2.12 and later. Update the list in a pipe instead. The expressions below give the same result

dict_default: "{{ list1|items2dict(key_name='uid', value_name='gid') }}"
dict_x: "{{ dict_default|
            combine(dict(list2|product([300]) + list3|product([400]))) }}"
gid_x: "{{ list1|map(attribute='uid')|map('extract', dict_x)|list }}"
gid_x_update: "{{ gid_x|map('community.general.dict_kv', 'gid')|list }}"
list4: "{{ list1|zip(gid_x_update)|map('combine')|list }}"
Details
dict_default:
  100: 250
  101: 250
  103: 250
  104: 250

dict_x: 100: 300 101: 300 102: 400 103: 400 104: 250

gid_x:

  • 300
  • 300
  • 400
  • 250

gid_x_update:

  • gid: 300
  • gid: 300
  • gid: 400
  • gid: 250