def build_components(scaling_components: list, id: int = 0):
    """
    Given a list of components and their instances, this function generates all possible combinations
    between them.

    Args:
        scaling_components (list, optional): A list of dictionaries for each scaling component. Defaults to []
        id (int, optional): The start of the recursion. Defaults to 0
    Returns:
        combinations (list): A list of all possible combinations
    """
    combinations = []

    if id >= len(scaling_components):
        return combinations

    rest = build_components(scaling_components, id+1)

    for inst in range(scaling_components[id]["Lower-Bound"], scaling_components[id]["Upper-Bound"] + 1):        
        if rest != []:
            for item in rest:
                item.append({"name": scaling_components[id]["Name"], "inst": inst})
            combinations = rest
        else:
            combinations.append([{"name": scaling_components[id]["Name"], "inst": inst}])
    return combinations