Need To Create List Of Dictionary With New Field 'device_id' Added

I have my code written like below .
But i am not able to get proper List of dictionary.

---
- name: Create final list by adding device_id to san_mount_list without exceeding size_gb
  hosts: localhost
  gather_facts: false
  vars:
    my_remain_space: 0
    my_hard_disk_converted_to_GB:
      - device_id: 2
        size: 32212254725
        size_gb: 30
      - device_id: 3
        size: 32212254724
        size_gb: 30

    san_mount_list_converted_to_GB:
      - no_of_vols: 1
        cap_unit: 'BYTES'
        size_gb: 9.74
        size: 10475277143
        mount_point: G

      - no_of_vols: 1
        cap_unit: 'BYTES'
        size_gb: 29.85
        size: 32212254723
        mount_point: H

      - no_of_vols: 1
        cap_unit: 'BYTES'
        size_gb: 9.75
        size: 10475277144
        mount_point: F

      - no_of_vols: 1
        cap_unit: 'BYTES'
        size_gb: 9.78
        size: 10475277145
        mount_point: H


  tasks:
    - name: "Convert 'san_mount_list_converted_to_GB' With Sorted To 'size_gb'"
      ansible.builtin.set_fact:
        my_hard_disk_converted_to_GB_sorted_decending: "{{ my_hard_disk_converted_to_GB | sort(attribute='size') }}"
        san_mount_list_converted_to_GB_sorted_ascending: "{{ san_mount_list_converted_to_GB | sort(attribute='size_gb') }}"




    - name: "Set Fact 'my_final_list'"
      ansible.builtin.set_fact:
        final_full_lun_details: "{{ final_full_lun_details | default([]) + [{ 'no_of_vols': item.1.no_of_vols, 'cap_unit': item.1.cap_unit, 'size': item.1.size, 'size_gb': item.1.size_gb, 'mount_point': item.1.mount_point, 'device_id': item.0.device_id }] }}"
        my_device_id: "{{ my_device_id | default([]) + [item.0.device_id] }}"
        my_remain_space: "{{ my_remain_space | int - item.1.size_gb | int | round(2) }}"
      when:
        - item.0.size_gb | int | round(2) >= item.1.size_gb | int | round(2)
        # - item.0.device_id not in my_device_id | default([])
        - my_remain_space | int > item.1.size_gb | int | round(2)
      with_nested:
        - "{{ my_hard_disk_converted_to_GB_sorted_decending }}"
        - "{{ san_mount_list_converted_to_GB_sorted_ascending }}"
      vars:
        my_disk_size: "{{ item.0.size_gb | int | round(2) }}"
        my_remain_space: "{{ my_disk_size }}"


    - name: "Print my_final_list"
      ansible.builtin.debug:
        var: final_full_lun_details

I have 2 list

my_hard_disk_converted_to_GB:
  - device_id: 2
    size: 32212254725
    size_gb: 30
  - device_id: 3
    size: 32212254724
    size_gb: 30


san_mount_list_converted_to_GB:
  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 29.85
    size: 32212254723
    mount_point: H

  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 9.75
    size: 10475277144
    mount_point: F

  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 9.78
    size: 10475277145
    mount_point: H

  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 9.74
    size: 10475277143
    mount_point: G

I want to create a final_list
which will add device_id on san_mount_list_converted_to_GB and doesn’t cross size_gb of my_hard_disk_converted_to_GB.

san_mount_list_converted_to_GB:
  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 29.85
    size: 32212254723
    mount_point: H
    device_id: 2

  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 9.75
    size: 10475277144
    mount_point: F
    device_id: 3

  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 9.78
    size: 10475277145
    mount_point: H
    device_id: 3

  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 9.74
    size: 10475277143
    mount_point: G
    device_id: 3

What is the relationship between items in the two lists? Put another way, how are you supposed to know what device_id each item in san_mount_list_converted_to_GB gets?

my_hard_disk_converted_to_GB:
- device_id: 2
size: 32212254725
size_gb: 50
- device_id: 3
size: 32212254724
size_gb: 50
- device_id: 4
size: 32212254723
size_gb: 50

san_mount_list_converted_to_GB:
- no_of_vols: 1
cap_unit: ‘BYTES’
size_gb: 49.84
size: 50475274245
mount_point: G
device_id: 12
- no_of_vols: 1
cap_unit: ‘BYTES’
size_gb: 9.84
size: 10475274245
mount_point: G
device_id: 13
- no_of_vols: 1
cap_unit: ‘BYTES’
size_gb: 39.85
size: 404752742465
mount_point: F
device_id: 13
- no_of_vols: 1
cap_unit: ‘BYTES’
size_gb: 9.87
size: 10475274240
mount_point: F
device_id: 14
- no_of_vols: 1
cap_unit: ‘BYTES’
size_gb: 19.89
size: 11932554240
mount_point: H
device_id: 14
- no_of_vols: 1
cap_unit: ‘BYTES’
size_gb: 19.92
size: 11932554240
mount_point: I
device_id: 14

This is new 2 list I have now … It is having only size sum match … where device_id is different.
So 2 supposed to be replaced 12
So 3 supposed to be replaced 13
So 4 supposed to be replaced 14

Im afraid I still dont understand the relationship between the two lists. I dont see any matching sizes or size_gbs in the two lists

So 2 supposed to be replaced 12
So 3 supposed to be replaced 13
So 4 supposed to be replaced 14

I dont understand this either. Are you saying device_id 2 should be replaced with device_id: 12? Or the second item in the first list should be replaced by the 12th item in the second list?

server 'A" was having 3 LUN DIsk [with ID 12 and 13 and 14] and was having drives created over there. [List : san_mount_list_converted_to_GB].

I got server ‘B’ which is having same count of disk [with ID 2 and 3 and 4]
I want to create same drive over server ‘B’. [List :my_hard_disk_converted_to_GB].

Since Server ‘B’ don’t have 12,13,14 I want them to be replaced by 2,3,4 respectively.

Hope this helps. If you wanted to specify your own device ID mapping, the playbook could be simpler

- hosts: localhost
  gather_facts: false
  vars_files:
    - my_hard_disk_converted_to_GB.yml
    - san_mount_list_converted_to_GB.yml
  tasks:
    - name: Get Unique Device IDs Lists
      ansible.builtin.set_fact:
        my_hard_disk_converted_to_GB_device_ids: >-
          {{ my_hard_disk_converted_to_GB | map(attribute='device_id') | unique }}
        san_mount_list_converted_to_GB_device_ids: >-
          {{ san_mount_list_converted_to_GB | map(attribute='device_id') | unique }}
    - name: Create New san_mount_list_converted_to_GB
      ansible.builtin.set_fact:
        new_san_mount_list_converted_to_GB: >-
          {{ new_san_mount_list_converted_to_GB | default([]) +
          [item | combine({'device_id': _device_id_map[item['device_id']]})] }}
      loop: "{{ san_mount_list_converted_to_GB }}"
      vars:
        _device_id_map: >-
          {{ my_hard_disk_converted_to_GB_device_ids | zip(san_mount_list_converted_to_GB_device_ids) |
          map('reverse') | community.general.dict }}
    - name: Print New List
      ansible.builtin.debug:
        var: new_san_mount_list_converted_to_GB

Apology For late response
This is probably the best solution.


  • name: “Mapping SAN Mount Drive With Source/Old Device ID And Target/new Device ID”
    hosts: localhost
    gather_facts: false
    vars:

    my_hard_disk_converted_to_GB:

    - { device_id: 1, size: 32212254720, size_gb: 300.0 } # 11

    - { cap_unit: “BYTES”, device_id: 11, mount_point: “H”, no_of_vols: “1”, size: 10479468544, size_gb: 250.00 }

    - { cap_unit: “BYTES”, device_id: 11, mount_point: “J”, no_of_vols: “1”, size: 31460425728, size_gb: 50.00 } # noqa yaml[colons]

    - { device_id: 3, size: 32212254720, size_gb: 100.0 } # 14

    - { cap_unit: “BYTES”, device_id: 14, mount_point: “E”, no_of_vols: “1”, size: 31460425728, size_gb: 50.00 } # noqa yaml[colons]

    - { cap_unit: “BYTES”, device_id: 14, mount_point: “J”, no_of_vols: “1”, size: 31460425728, size_gb: 50.00 } # noqa yaml[colons]

    - { device_id: 2, size: 32212254720, size_gb: 400.0 } # 12

    - { cap_unit: “BYTES”, device_id: 12, mount_point: “G”, no_of_vols: “1”, size: 10479468544, size_gb: 400.00 }

    - { device_id: 4, size: 32212254720, size_gb: 100.0 } # 13

    - { cap_unit: “BYTES”, device_id: 13, mount_point: “F”, no_of_vols: “1”, size: 10479468544, size_gb: 100.00 }

    - { device_id: 5, size: 32212254720, size_gb: 500.0 } # 15

    - { cap_unit: “BYTES”, device_id: 15, mount_point: “I”, no_of_vols: “1”, size: 31460425728, size_gb: 500.00 }

    my_hard_disk_converted_to_GB:
    - { device_id: 1, size: 32212254720, size_gb: 300.0 } # 11
    - { device_id: 3, size: 32212254720, size_gb: 100.0 } # 14
    - { device_id: 2, size: 32212254720, size_gb: 400.0 } # 12
    - { device_id: 4, size: 32212254720, size_gb: 100.0 } # 13
    - { device_id: 5, size: 32212254720, size_gb: 500.0 } # 15
    san_mount_drive_details_converted_to_GB:
    - { cap_unit: “BYTES”, device_id: 13, mount_point: “F”, no_of_vols: “1”, size: 10479468544, size_gb: 100.00 }
    - { cap_unit: “BYTES”, device_id: 11, mount_point: “H”, no_of_vols: “1”, size: 10479468544, size_gb: 250.00 }
    - { cap_unit: “BYTES”, device_id: 15, mount_point: “I”, no_of_vols: “1”, size: 31460425728, size_gb: 500.00 }
    - { cap_unit: “BYTES”, device_id: 14, mount_point: “E”, no_of_vols: “1”, size: 31460425728, size_gb: 50.00 } # noqa yaml[colons]
    - { cap_unit: “BYTES”, device_id: 11, mount_point: “J”, no_of_vols: “1”, size: 31460425728, size_gb: 50.00 } # noqa yaml[colons]
    - { cap_unit: “BYTES”, device_id: 12, mount_point: “G”, no_of_vols: “1”, size: 10479468544, size_gb: 400.00 }
    - { cap_unit: “BYTES”, device_id: 14, mount_point: “J”, no_of_vols: “1”, size: 31460425728, size_gb: 50.00 } # noqa yaml[colons]

    san_mount_drive_details_converted_to_GB:

    - { cap_unit: “BYTES”, device_id: 13, mount_point: “F”, no_of_vols: “1”, size: 10479468544, size_gb: 90.00 } # noqa yaml[colons]

    - { cap_unit: “BYTES”, device_id: 11, mount_point: “H”, no_of_vols: “1”, size: 10479468544, size_gb: 245.00 }

    - { cap_unit: “BYTES”, device_id: 15, mount_point: “I”, no_of_vols: “1”, size: 31460425728, size_gb: 480.00 }

    - { cap_unit: “BYTES”, device_id: 14, mount_point: “E”, no_of_vols: “1”, size: 31460425728, size_gb: 45.00 } # noqa yaml[colons]

    - { cap_unit: “BYTES”, device_id: 11, mount_point: “J”, no_of_vols: “1”, size: 31460425728, size_gb: 50.00 } # noqa yaml[colons]

    - { cap_unit: “BYTES”, device_id: 12, mount_point: “G”, no_of_vols: “1”, size: 10479468544, size_gb: 390.00 }

    - { cap_unit: “BYTES”, device_id: 14, mount_point: “J”, no_of_vols: “1”, size: 31460425728, size_gb: 40.00 } # noqa yaml[colons]

    tasks:

    • name: “Fetch Total Size Used Per Device-IDs By Looping Over ‘san_mount_drive_details_converted_to_GB’”
      ansible.builtin.set_fact:
      total_size_per_device: “{{total_size_per_device | default({}) | combine({item.device_id: (total_size_per_device[item.device_id] | default(0)) + item.size_gb}) }}”
      loop: “{{ san_mount_drive_details_converted_to_GB }}”
      loop_control:
      label: “{{ item.device_id }}”

    • name: “Format ‘total_size_per_device’ Total Size Used Per Device-IDs”
      ansible.builtin.set_fact:
      final_total_size_per_device: “{{ final_total_size_per_device | default() + [{‘device_id’:item.key, ‘size_gb’: item.value}] }}”
      loop: “{{ total_size_per_device | dict2items }}”

    • name: “Print Total Size Used Per Device-IDs”
      ansible.builtin.debug:
      var: final_total_size_per_device

    • name: “Initialize Empty Lists For Device Mappings And Processed Device-IDs”
      ansible.builtin.set_fact:
      device_mapping_list:
      processed_source_device_ids:
      processed_target_device_ids:

    • name: “Map ‘source_device_id’ With ‘target_device_id’ Pairs Without Duplicates”
      ansible.builtin.set_fact:
      device_mapping_list: “{{ device_mapping_list + [{‘source_device_id’: item.0.device_id, ‘target_device_id’: item.1.device_id}] }}”
      processed_source_device_ids: “{{ processed_source_device_ids + [item.0.device_id] }}”
      processed_target_device_ids: “{{ processed_target_device_ids + [item.1.device_id] }}”
      when:

      • item.0.device_id not in processed_source_device_ids
      • item.1.device_id not in processed_target_device_ids
      • item.1.size_gb | float >= item.0.size_gb | float

      - item.1.size_gb | float == item.0.size_gb | float

      with_nested:

      • “{{ final_total_size_per_device | sort(attribute=‘size_gb’) | reverse }}”
      • “{{ my_hard_disk_converted_to_GB }}”
    • name: “Display ‘device_mapping_list’”
      ansible.builtin.debug:
      var: device_mapping_list

    • name: “Map And Replace ‘source_device_id’ With ‘target_device_id’ On Var ‘san_mount_drive_details_converted_to_GB’”
      ansible.builtin.set_fact:
      final_mapped_san_mount_drive_details: “{{ final_mapped_san_mount_drive_details | default() + [
      {
      ‘device_id’: item.0.target_device_id,
      ‘size_gb’: item.1.size_gb,
      ‘mount_point’: item.1.mount_point,
      ‘no_of_vols’: item.1.no_of_vols,
      ‘size’: item.1.size,
      ‘cap_unit’: item.1.cap_unit
      }] }}”
      when: item.0.source_device_id | int == item.1.device_id | int
      with_nested:

      • “{{ device_mapping_list }}”
      • “{{ san_mount_drive_details_converted_to_GB }}”
    • name: “Show Final ‘final_mapped_san_mount_drive_details’”
      ansible.builtin.debug:
      var: final_mapped_san_mount_drive_details

Could you enclose the YAML in three backticks to improve the formatting? See for example the GitHub guide.