A standard Python library that abstracts away differences among multiple cloud provider APIs
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
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 providersfrom 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 enumReturns:
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')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) -> DictBase 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 accountcreate_balancer(): Create a new load balancerdestroy_balancer(): Delete a load balancerbalancer_attach_member(): Add a member to a load balancerbalancer_detach_member(): Remove a member from a load balancerbalancer_attach_compute_node(): Attach a compute node as a memberclass 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) -> boolRepresents a load balancer instance.
Properties:
id: Unique load balancer identifiername: Human-readable namestate: Current state (running, pending, unknown, etc.)ip: Load balancer IP address or DNS nameport: Port number the load balancer listens onextra: Provider-specific metadataMethods:
attach_member(): Add a member to this load balancerdetach_member(): Remove a member from this load balancerlist_members(): List all members attached to this load balancerdestroy(): Delete this load balancerclass 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 identifierip: Member IP addressport: Port number on the memberbalancer: Parent load balancerextra: Provider-specific metadata (health status, weight, etc.)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.
class State:
"""Load balancer states"""
RUNNING = 0
PENDING = 1
UNKNOWN = 2
DELETED = 3Enumeration of possible load balancer states.
class MemberCondition:
"""Member health conditions"""
ENABLED = 'enabled'
DISABLED = 'disabled'
DRAINING = 'draining'Enumeration of member health/status conditions.
DEFAULT_ALGORITHM: Algorithm = Algorithm.ROUND_ROBINDefault load balancing algorithm used when none is specified.
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}")# 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}")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}")# 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")# 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)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)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)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)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')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")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