Compare lists of dictionaries representing Azure objects. Only keys found in the "new" dictionaries are compared to
    the "old" dictionaries, since getting Azure objects from the API returns some read-only data which should not be
    used in the comparison. A list of parameter names can be passed in order to compare a bare object name to a full
    Azure ID path for brevity. If string types are found in values, comparison is case insensitive. Return comment
    should be used to trigger exit from the calling function.

def compare_list_of_dicts(old, new, convert_id_to_name=None):
    '''
    Compare lists of dictionaries representing Azure objects. Only keys found in the "new" dictionaries are compared to
    the "old" dictionaries, since getting Azure objects from the API returns some read-only data which should not be
    used in the comparison. A list of parameter names can be passed in order to compare a bare object name to a full
    Azure ID path for brevity. If string types are found in values, comparison is case insensitive. Return comment
    should be used to trigger exit from the calling function.
    '''
    ret = {}

    if not convert_id_to_name:
        convert_id_to_name = []

    if not isinstance(new, list):
        ret['comment'] = 'must be provided as a list of dictionaries!'
        return ret

    if len(new) != len(old):
        ret['changes'] = {
            'old': old,
            'new': new
        }
        return ret

    try:
        local_configs, remote_configs = [sorted(config, key=itemgetter('name')) for config in (new, old)]
    except TypeError:
        ret['comment'] = 'configurations must be provided as a list of dictionaries!'
        return ret
    except KeyError:
        ret['comment'] = 'configuration dictionaries must contain the "name" key!'
        return ret

    for idx in six_range(0, len(local_configs)):
        for key in local_configs[idx]:
            local_val = local_configs[idx][key]
            if key in convert_id_to_name:
                remote_val = remote_configs[idx].get(key, {}).get('id', '').split('/')[-1]
            else:
                remote_val = remote_configs[idx].get(key)
                if isinstance(local_val, six.string_types):
                    local_val = local_val.lower()
                if isinstance(remote_val, six.string_types):
                    remote_val = remote_val.lower()
            if local_val != remote_val:
                ret['changes'] = {
                    'old': remote_configs,
                    'new': local_configs
                }
                return ret

    return ret