CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-apache-libcloud

A standard Python library that abstracts away differences among multiple cloud provider APIs

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

load-balancer-services.mddocs/

Load Balancer Services

The load balancer service provides a unified interface for load balancer management across multiple cloud providers including AWS ELB/ALB, Azure Load Balancer, Google Load Balancer, Rackspace Load Balancer, and others.

Providers

from libcloud.loadbalancer.types import Provider

class Provider:
    """Enumeration of supported load balancer providers"""
    ELB = 'elb'                    # AWS Elastic Load Balancer
    ALB = 'alb'                    # AWS Application Load Balancer  
    GCE = 'gce'                    # Google Cloud Load Balancer
    RACKSPACE = 'rackspace'        # Rackspace Cloud Load Balancers
    NINEFOLD = 'ninefold'          # Ninefold Load Balancer
    BRIGHTBOX = 'brightbox'        # Brightbox Load Balancer
    CLOUDSTACK = 'cloudstack'      # CloudStack Load Balancer
    DIMENSIONDATA = 'dimensiondata' # Dimension Data Load Balancer
    # ... more providers

Driver Factory

from libcloud.loadbalancer.providers import get_driver

def get_driver(provider: Provider) -> type[Driver]

Get the driver class for a specific load balancer provider.

Parameters:

  • provider: Provider identifier from the Provider enum

Returns:

  • Driver class for the specified provider

Example:

from libcloud.loadbalancer.types import Provider
from libcloud.loadbalancer.providers import get_driver

# Get AWS ELB driver class
cls = get_driver(Provider.ELB)

# Initialize driver with credentials
driver = cls('access_key', 'secret_key', region='us-east-1')

Core Classes

Driver

class Driver(BaseDriver):
    """Base class for all load balancer drivers"""
    
    def list_protocols(self) -> List[str]
    def list_balancers(self) -> List[LoadBalancer]
    def create_balancer(self, name: str, port: int, protocol: str, algorithm: Algorithm, members: List[Member]) -> LoadBalancer
    def destroy_balancer(self, balancer: LoadBalancer) -> bool
    def get_balancer(self, balancer_id: str) -> LoadBalancer
    def update_balancer(self, balancer: LoadBalancer, **kwargs) -> LoadBalancer
    def balancer_list_members(self, balancer: LoadBalancer) -> List[Member]
    def balancer_attach_member(self, balancer: LoadBalancer, member: Member) -> bool
    def balancer_detach_member(self, balancer: LoadBalancer, member: Member) -> bool
    def balancer_attach_compute_node(self, balancer: LoadBalancer, node: Node) -> Member
    def balancer_detach_compute_node(self, balancer: LoadBalancer, node: Node) -> bool
    def ex_list_balancer_health_checks(self, balancer: LoadBalancer) -> List[Dict]
    def ex_create_balancer_health_check(self, balancer: LoadBalancer, **kwargs) -> Dict

Base class that all load balancer drivers inherit from. Provides methods for managing load balancers and their members.

Key Methods:

  • list_balancers(): List all load balancers in the account
  • create_balancer(): Create a new load balancer
  • destroy_balancer(): Delete a load balancer
  • balancer_attach_member(): Add a member to a load balancer
  • balancer_detach_member(): Remove a member from a load balancer
  • balancer_attach_compute_node(): Attach a compute node as a member

LoadBalancer

class LoadBalancer:
    """Represents a load balancer"""
    
    id: str
    name: str
    state: State
    ip: str
    port: int
    driver: Driver
    extra: Dict[str, Any]
    
    def attach_member(self, member: Member) -> bool
    def detach_member(self, member: Member) -> bool  
    def list_members(self) -> List[Member]
    def destroy(self) -> bool

Represents a load balancer instance.

Properties:

  • id: Unique load balancer identifier
  • name: Human-readable name
  • state: Current state (running, pending, unknown, etc.)
  • ip: Load balancer IP address or DNS name
  • port: Port number the load balancer listens on
  • extra: Provider-specific metadata

Methods:

  • attach_member(): Add a member to this load balancer
  • detach_member(): Remove a member from this load balancer
  • list_members(): List all members attached to this load balancer
  • destroy(): Delete this load balancer

Member

class Member:
    """Represents a load balancer member/target"""
    
    id: str
    ip: str
    port: int
    balancer: LoadBalancer
    extra: Dict[str, Any]

Represents a member (backend server) attached to a load balancer.

Properties:

  • id: Unique member identifier
  • ip: Member IP address
  • port: Port number on the member
  • balancer: Parent load balancer
  • extra: Provider-specific metadata (health status, weight, etc.)

Algorithm

class Algorithm:
    """Load balancing algorithms"""
    ROUND_ROBIN = 'round_robin'
    LEAST_CONNECTIONS = 'least_connections'
    RANDOM = 'random'
    WEIGHTED_ROUND_ROBIN = 'weighted_round_robin'
    WEIGHTED_LEAST_CONNECTIONS = 'weighted_least_connections'
    SOURCE_IP = 'source_ip'

Enumeration of supported load balancing algorithms.

State

class State:
    """Load balancer states"""
    RUNNING = 0
    PENDING = 1
    UNKNOWN = 2
    DELETED = 3

Enumeration of possible load balancer states.

MemberCondition

class MemberCondition:
    """Member health conditions"""
    ENABLED = 'enabled'
    DISABLED = 'disabled'
    DRAINING = 'draining'

Enumeration of member health/status conditions.

DEFAULT_ALGORITHM

DEFAULT_ALGORITHM: Algorithm = Algorithm.ROUND_ROBIN

Default load balancing algorithm used when none is specified.

Usage Examples

Basic Load Balancer Management

from libcloud.loadbalancer.types import Provider, Algorithm
from libcloud.loadbalancer.providers import get_driver

# Initialize driver
cls = get_driver(Provider.ELB)
driver = cls('access_key', 'secret_key', region='us-east-1')

# List existing load balancers
balancers = driver.list_balancers()
for balancer in balancers:
    print(f"Load Balancer: {balancer.name} ({balancer.state}) - {balancer.ip}:{balancer.port}")

# Check supported protocols
protocols = driver.list_protocols()
print(f"Supported protocols: {protocols}")

# Create members for the load balancer
members = [
    Member(id=None, ip='10.0.1.10', port=80, balancer=None),
    Member(id=None, ip='10.0.1.11', port=80, balancer=None),
    Member(id=None, ip='10.0.1.12', port=80, balancer=None)
]

# Create a new load balancer
balancer = driver.create_balancer(
    name='web-lb',
    port=80,
    protocol='http',
    algorithm=Algorithm.ROUND_ROBIN,
    members=members
)
print(f"Created load balancer: {balancer.name} ({balancer.id})")
print(f"Load balancer IP: {balancer.ip}")

Managing Load Balancer Members

# Get an existing load balancer
balancer = driver.get_balancer('lb-12345')

# List current members
current_members = balancer.list_members()
print(f"Current members: {len(current_members)}")

for member in current_members:
    print(f"  Member: {member.ip}:{member.port} (ID: {member.id})")
    if 'condition' in member.extra:
        print(f"    Status: {member.extra['condition']}")

# Add a new member
new_member = Member(id=None, ip='10.0.1.13', port=80, balancer=balancer)
success = balancer.attach_member(new_member)
print(f"Added new member: {success}")

# Alternative: Add using driver method
success = driver.balancer_attach_member(balancer, new_member)
print(f"Added member via driver: {success}")

# Remove a member
if current_members:
    member_to_remove = current_members[0]
    success = balancer.detach_member(member_to_remove)
    print(f"Removed member {member_to_remove.ip}: {success}")

Integration with Compute Nodes

from libcloud.compute.types import Provider as ComputeProvider
from libcloud.compute.providers import get_driver as get_compute_driver

# Initialize compute driver
compute_cls = get_compute_driver(ComputeProvider.EC2)
compute_driver = compute_cls('access_key', 'secret_key', region='us-east-1')

# Get existing compute nodes
nodes = compute_driver.list_nodes()
web_servers = [node for node in nodes if 'web' in node.name.lower()]

print(f"Found {len(web_servers)} web server nodes")

# Attach compute nodes to load balancer
for node in web_servers[:3]:  # Attach first 3 web servers
    if node.private_ips:  # Use private IP for internal load balancing
        member = driver.balancer_attach_compute_node(balancer, node)
        print(f"Attached node {node.name} ({node.private_ips[0]}) as member {member.id}")

# Alternative: Detach a compute node
if web_servers:
    node_to_detach = web_servers[0]
    success = driver.balancer_detach_compute_node(balancer, node_to_detach)
    print(f"Detached node {node_to_detach.name}: {success}")

Advanced Load Balancer Configuration

# Create load balancer with advanced configuration
advanced_members = [
    Member(id=None, ip='10.0.1.10', port=80, balancer=None),
    Member(id=None, ip='10.0.1.11', port=80, balancer=None)
]

# AWS ELB specific configuration
elb_balancer = driver.create_balancer(
    name='advanced-web-lb',
    port=443,  # HTTPS
    protocol='https',
    algorithm=Algorithm.LEAST_CONNECTIONS,
    members=advanced_members
)

print(f"Created HTTPS load balancer: {elb_balancer.name}")

# Configure health checks (provider specific)
try:
    health_checks = driver.ex_list_balancer_health_checks(elb_balancer)
    print(f"Current health checks: {len(health_checks)}")
    
    # Create custom health check
    health_check = driver.ex_create_balancer_health_check(
        balancer=elb_balancer,
        target='HTTP:80/health',
        interval=30,
        timeout=5,
        healthy_threshold=2,
        unhealthy_threshold=5
    )
    print(f"Created health check: {health_check}")
    
except AttributeError:
    print("Health check configuration not available for this provider")

Multi-Protocol Load Balancer

# Create load balancer for multiple protocols (if supported)
def create_multi_protocol_lb(driver, name, members):
    """Create load balancers for different protocols"""
    protocols = ['http', 'https', 'tcp']
    balancers = {}
    
    for protocol in protocols:
        port = 80 if protocol == 'http' else (443 if protocol == 'https' else 8080)
        
        try:
            balancer = driver.create_balancer(
                name=f'{name}-{protocol}',
                port=port,
                protocol=protocol,
                algorithm=Algorithm.ROUND_ROBIN,
                members=members
            )
            balancers[protocol] = balancer
            print(f"Created {protocol.upper()} load balancer: {balancer.ip}:{balancer.port}")
            
        except Exception as e:
            print(f"Failed to create {protocol} load balancer: {e}")
    
    return balancers

# Usage
multi_members = [
    Member(id=None, ip='10.0.1.10', port=80, balancer=None),
    Member(id=None, ip='10.0.1.11', port=80, balancer=None)
]

protocol_balancers = create_multi_protocol_lb(driver, 'api-lb', multi_members)

Load Balancer Monitoring and Health Management

import time
from typing import Dict, List

def monitor_load_balancer_health(driver, balancer, interval: int = 60):
    """Monitor load balancer and member health"""
    print(f"Monitoring load balancer: {balancer.name}")
    
    while True:
        try:
            # Refresh balancer state
            current_balancer = driver.get_balancer(balancer.id)
            print(f"Load balancer state: {current_balancer.state}")
            
            # Check member health
            members = driver.balancer_list_members(current_balancer)
            healthy_members = 0
            
            for member in members:
                status = member.extra.get('condition', 'unknown')
                health = member.extra.get('health_status', 'unknown')
                
                print(f"  Member {member.ip}:{member.port} - Status: {status}, Health: {health}")
                
                if status == 'enabled' and health == 'healthy':
                    healthy_members += 1
            
            print(f"Healthy members: {healthy_members}/{len(members)}")
            
            # Alert if too few healthy members
            if healthy_members < 2:
                print("WARNING: Less than 2 healthy members!")
                # Here you could send alerts, create new instances, etc.
            
        except Exception as e:
            print(f"Error monitoring load balancer: {e}")
        
        time.sleep(interval)

def manage_member_weights(driver, balancer, member_weights: Dict[str, int]):
    """Update member weights for weighted load balancing"""
    members = driver.balancer_list_members(balancer)
    
    for member in members:
        member_key = f"{member.ip}:{member.port}"
        if member_key in member_weights:
            weight = member_weights[member_key]
            
            # This is provider-specific - check your provider's documentation
            try:
                # Update member with new weight (example for providers that support it)
                updated_member = driver.ex_update_balancer_member(
                    balancer, member, weight=weight
                )
                print(f"Updated weight for {member_key} to {weight}")
            except AttributeError:
                print(f"Weight management not supported by this provider")

# Usage examples
balancer = driver.get_balancer('lb-12345')

# Set different weights for members
weights = {
    '10.0.1.10:80': 100,  # Full weight
    '10.0.1.11:80': 75,   # Reduced weight  
    '10.0.1.12:80': 50    # Half weight
}

manage_member_weights(driver, balancer, weights)

# Start monitoring (run in separate thread/process)
# monitor_load_balancer_health(driver, balancer, interval=30)

Auto-Scaling Integration

def auto_scale_load_balancer(compute_driver, lb_driver, balancer, template_node, min_members=2, max_members=10):
    """Auto-scale load balancer members based on health"""
    
    members = lb_driver.balancer_list_members(balancer)
    healthy_members = sum(1 for m in members if m.extra.get('health_status') == 'healthy')
    
    print(f"Current members: {len(members)}, Healthy: {healthy_members}")
    
    # Scale up if too few healthy members
    if healthy_members < min_members and len(members) < max_members:
        print("Scaling up: Creating new compute node...")
        
        # Create new compute node based on template
        new_node = compute_driver.create_node(
            name=f"auto-web-{int(time.time())}",
            size=template_node.size,
            image=template_node.image,
            location=template_node.extra.get('availability_zone')
        )
        
        # Wait for node to be running
        compute_driver.wait_until_running([new_node])
        
        # Add to load balancer
        new_member = lb_driver.balancer_attach_compute_node(balancer, new_node)
        print(f"Added new member: {new_member.ip}:{new_member.port}")
    
    # Scale down if too many healthy members
    elif healthy_members > max_members:
        print("Scaling down: Removing excess members...")
        
        # Find oldest member to remove
        members_by_age = sorted(members, key=lambda m: m.extra.get('created_time', ''))
        member_to_remove = members_by_age[0]
        
        # Remove from load balancer
        success = lb_driver.balancer_detach_member(balancer, member_to_remove)
        if success:
            print(f"Removed member: {member_to_remove.ip}:{member_to_remove.port}")
            
            # Optionally terminate the compute node
            # node_to_terminate = compute_driver.get_node(member_to_remove.extra.get('node_id'))
            # compute_driver.destroy_node(node_to_terminate)

# Usage
template_node = compute_driver.list_nodes()[0]  # Use existing node as template
auto_scale_load_balancer(compute_driver, driver, balancer, template_node)

Cross-Provider Load Balancer Management

from libcloud.loadbalancer.types import Provider
from libcloud.loadbalancer.providers import get_driver

# Configure multiple load balancer providers
lb_providers = {
    'aws_elb': {
        'driver': get_driver(Provider.ELB),
        'credentials': ('aws_access_key', 'aws_secret_key'),
        'region': 'us-east-1'
    },
    'gce_lb': {
        'driver': get_driver(Provider.GCE),
        'credentials': ('service_account_email', 'key_file_path'),
        'project': 'my-project'
    }
}

# Initialize drivers
lb_drivers = {}
for name, config in lb_providers.items():
    cls = config['driver']
    if 'region' in config:
        lb_drivers[name] = cls(*config['credentials'], region=config['region'])
    elif 'project' in config:
        lb_drivers[name] = cls(*config['credentials'], project=config['project'])

# Create similar load balancers across providers for redundancy
def create_redundant_load_balancers(providers_config, name, members):
    """Create load balancers across multiple providers for redundancy"""
    balancers = {}
    
    for provider_name, driver in lb_drivers.items():
        try:
            balancer = driver.create_balancer(
                name=f'{name}-{provider_name}',
                port=80,
                protocol='http',
                algorithm=Algorithm.ROUND_ROBIN,
                members=members
            )
            balancers[provider_name] = balancer
            print(f"Created load balancer on {provider_name}: {balancer.ip}")
            
        except Exception as e:
            print(f"Failed to create load balancer on {provider_name}: {e}")
    
    return balancers

# Create members for each provider (adjust IPs as needed)
aws_members = [
    Member(id=None, ip='10.0.1.10', port=80, balancer=None),
    Member(id=None, ip='10.0.1.11', port=80, balancer=None)
]

gce_members = [
    Member(id=None, ip='10.1.1.10', port=80, balancer=None),
    Member(id=None, ip='10.1.1.11', port=80, balancer=None)
]

# Create redundant load balancers
redundant_lbs = create_redundant_load_balancers(lb_providers, 'global-api', aws_members)

Load Balancer Configuration Backup and Restore

import json
from datetime import datetime

def backup_load_balancer_config(driver, balancer) -> Dict:
    """Create a backup of load balancer configuration"""
    
    members = driver.balancer_list_members(balancer)
    
    backup_data = {
        'balancer': {
            'name': balancer.name,
            'port': balancer.port,
            'state': balancer.state,
            'extra': balancer.extra
        },
        'members': [
            {
                'ip': member.ip,
                'port': member.port,
                'extra': member.extra
            }
            for member in members
        ],
        'backup_timestamp': datetime.now().isoformat()
    }
    
    # Try to get health checks if supported
    try:
        health_checks = driver.ex_list_balancer_health_checks(balancer)
        backup_data['health_checks'] = health_checks
    except AttributeError:
        pass
    
    print(f"Backed up load balancer {balancer.name} with {len(members)} members")
    return backup_data

def restore_load_balancer_config(driver, backup_data, new_name=None):
    """Restore load balancer from backup"""
    
    balancer_config = backup_data['balancer']
    name = new_name or balancer_config['name']
    
    # Recreate members
    members = [
        Member(id=None, ip=m['ip'], port=m['port'], balancer=None)
        for m in backup_data['members']
    ]
    
    # Create load balancer
    try:
        restored_balancer = driver.create_balancer(
            name=name,
            port=balancer_config['port'],
            protocol=balancer_config['extra'].get('protocol', 'http'),
            algorithm=Algorithm.ROUND_ROBIN,
            members=members
        )
        
        print(f"Restored load balancer: {restored_balancer.name}")
        
        # Restore health checks if they were backed up
        if 'health_checks' in backup_data:
            for hc in backup_data['health_checks']:
                try:
                    driver.ex_create_balancer_health_check(restored_balancer, **hc)
                except (AttributeError, Exception) as e:
                    print(f"Could not restore health check: {e}")
        
        return restored_balancer
        
    except Exception as e:
        print(f"Failed to restore load balancer: {e}")
        return None

# Usage
balancer = driver.get_balancer('lb-12345')

# Create backup
backup = backup_load_balancer_config(driver, balancer)

# Save to file
with open(f'lb_backup_{balancer.name}_{datetime.now().strftime("%Y%m%d_%H%M%S")}.json', 'w') as f:
    json.dump(backup, f, indent=2)

# Restore from backup
restored_lb = restore_load_balancer_config(driver, backup, 'restored-lb')

Exception Handling

from libcloud.loadbalancer.types import LoadBalancerError
from libcloud.common.types import LibcloudError, InvalidCredsError

try:
    # Create load balancer
    balancer = driver.create_balancer(
        name='test-lb',
        port=80,
        protocol='http',
        algorithm=Algorithm.ROUND_ROBIN,
        members=members
    )
except InvalidCredsError:
    print("Invalid credentials for load balancer provider")
except LoadBalancerError as e:
    print(f"Load balancer specific error: {e}")
except LibcloudError as e:
    print(f"General Libcloud error: {e}")

# Check balancer state before operations
if balancer.state == State.RUNNING:
    success = driver.destroy_balancer(balancer)
elif balancer.state == State.PENDING:
    print("Load balancer is still being created")

Provider-Specific Features

Different providers offer additional features through the ex_* parameter pattern:

# AWS ELB specific features
elb_driver = get_driver(Provider.ELB)('access_key', 'secret_key')

# Create ELB with AWS-specific configuration
elb_balancer = elb_driver.create_balancer(
    name='aws-elb',
    port=80,
    protocol='http',
    algorithm=Algorithm.ROUND_ROBIN,
    members=members,
    ex_scheme='internet-facing',      # Internet-facing vs internal
    ex_security_groups=['sg-12345'],  # Security groups
    ex_subnets=['subnet-12345'],      # VPC subnets
    ex_cross_zone=True               # Cross-zone load balancing
)

# Google Cloud Load Balancer specific features
gce_driver = get_driver(Provider.GCE)('email', 'key_file', project='my-project')

# Create GCE load balancer with specific configuration
gce_balancer = gce_driver.create_balancer(
    name='gce-lb',
    port=80,
    protocol='http',
    algorithm=Algorithm.ROUND_ROBIN,
    members=members,
    ex_region='us-central1',          # Regional load balancer
    ex_session_affinity='CLIENT_IP'   # Session affinity
)

Check provider-specific documentation for additional capabilities available through the ex_* parameters and methods.

Install with Tessl CLI

npx tessl i tessl/pypi-apache-libcloud

docs

backup-services.md

compute-services.md

container-services.md

core-driver-system.md

dns-management.md

index.md

load-balancer-services.md

storage-services.md

tile.json