ansible - list with item index as hash

Viewed 245

I'm trying to add list element index as hash, preferably without using with_indexed_items because result is to be filtered later.

I'd like to convert this:

vmware_disks:
- datastore: "datastores0"
  size_gb: 24
- datastore: "datastores0"
  size_gb: 397
  storage_policy: "vSAN standard cluster RAID-1"

to something like this:

vmware_disks:
- datastore: "datastores0"
  size_gb: 24
  nr: 0
- datastore: "datastores0"
  size_gb: 397
  storage_policy: "vSAN standard cluster RAID-1"
  nr: 1

So far I was able to:

  • using "{{ vmware_disks | zip(range(0,2)) }}"
    [     
      {   
        "datastore": "datastores0",
        "size_gb": 24
      },  
      0   
    ],    
    [     
      {   
        "datastore": "datastores0",
        "size_gb": 397,
        "storage_policy": "vSAN standard cluster RAID-1"
      },  
      1   
    ]     
    
  • "{{ vmware_disks | map('combine', {'nr':0}) }}"
    [
      {
        "datastore": "datastores0",
        "nr": 0,
        "size_gb": 24
      },
        {
          "datastore": "datastores0",
        "nr": 0,
        "size_gb": 397,
        "storage_policy": "vSAN standard cluster RAID-1"
      }
    ]
    

Please help me to combine both to get desired result.

1 Answers

You can use a set_fact to create another dictionary and add the index in:

- set_fact: 
    indexed_vmware_disks: >-
      {{ 
        indexed_vmware_disks | default([]) 
          + [ item | combine( { 'nr': index } ) ] 
      }}
  loop: "{{ vmware_disks }}"
  loop_control:
    index_var: index

Then if you really need the dictionary to have the exact name it had before, you can just reassign it in another set_fact.

So an example playbook:

- hosts: all
  gather_facts: no
  vars:
    vmware_disks:
      - datastore: "datastores0"
        size_gb: 24
      - datastore: "datastores0"
        size_gb: 397
        storage_policy: "vSAN standard cluster RAID-1"

  tasks:
    - set_fact: 
        indexed_vmware_disks: >-
          {{ 
            indexed_vmware_disks | default([]) 
              + [ item | combine( { 'nr': index } ) ] 
          }}
      loop: "{{ vmware_disks }}"
      loop_control:
        index_var: index

    - set_fact: 
        vmware_disks: "{{ indexed_vmware_disks }}"

    - debug:
        var: vmware_disks

Would yield the recap:

PLAY [all] *******************************************************************************************************

TASK [set_fact] **************************************************************************************************
ok: [localhost] => (item={'datastore': 'datastores0', 'size_gb': 24})
ok: [localhost] => (item={'datastore': 'datastores0', 'size_gb': 397, 'storage_policy': 'vSAN standard cluster RAID-1'})

TASK [set_fact] **************************************************************************************************
ok: [localhost]

TASK [debug] *****************************************************************************************************
ok: [localhost] => 
  vmware_disks:
  - datastore: datastores0
    nr: 0
    size_gb: 24
  - datastore: datastores0
    nr: 1
    size_gb: 397
    storage_policy: vSAN standard cluster RAID-1

PLAY RECAP *******************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
Related