# python/01-blue-green-deployment.py"""Blue-green deployment patterns and zero-downtime deployment strategies"""fromtypingimportList,Dict,Any,Optional,Union,Tuplefromdataclassesimportdataclass,asdictfromenumimportEnumimporttimeimportjsonimportsubprocessimportrequestsfromdatetimeimportdatetime,timedeltaimportloggingimportthreadingfromconcurrent.futuresimportThreadPoolExecutor,as_completed# Configure logginglogging.basicConfig(level=logging.INFO)logger=logging.getLogger(__name__)classDeploymentStatus(Enum):"""Deployment status enumeration"""PENDING="pending"IN_PROGRESS="in_progress"SUCCESS="success"FAILED="failed"ROLLBACK="rollback"classEnvironment(Enum):"""Environment enumeration"""BLUE="blue"GREEN="green"@dataclassclassDeploymentConfig:"""Deployment configuration"""application_name:strversion:strenvironment:strreplicas:int=3cpu_limit:str="500m"memory_limit:str="512Mi"cpu_request:str="250m"memory_request:str="256Mi"health_check_path:str="/health"readiness_check_path:str="/ready"max_unavailable:int=1max_surge:int=1deployment_timeout:int=300rollback_timeout:int=180classBlueGreenDeployer:"""Blue-green deployment orchestrator"""def__init__(self,config:DeploymentConfig):self.config=configself.current_environment=Noneself.deployment_status=DeploymentStatus.PENDINGself.deployment_metrics={}self.health_checker=HealthChecker()self.load_balancer=LoadBalancer()defdetermine_current_environment(self)->Environment:"""Determine current active environment"""try:# Check which environment is currently receiving trafficblue_status=self.health_checker.check_environment_health("blue")green_status=self.health_checker.check_environment_health("green")ifblue_status["healthy"]andnotgreen_status["healthy"]:returnEnvironment.BLUEelifgreen_status["healthy"]andnotblue_status["healthy"]:returnEnvironment.GREENelse:# Default to blue if both are healthy or both are unhealthyreturnEnvironment.BLUEexceptExceptionase:logger.error(f"Error determining current environment: {e}")returnEnvironment.BLUEdefdeploy_to_environment(self,environment:Environment)->bool:"""Deploy application to specified environment"""try:self.deployment_status=DeploymentStatus.IN_PROGRESSstart_time=time.time()logger.info(f"Starting deployment to {environment.value} environment")# Update deployment configurationdeployment_manifest=self._create_deployment_manifest(environment)# Apply deploymentsuccess=self._apply_deployment(deployment_manifest,environment)ifnotsuccess:logger.error(f"Failed to apply deployment to {environment.value}")self.deployment_status=DeploymentStatus.FAILEDreturnFalse# Wait for deployment to be readyready=self._wait_for_deployment_ready(environment)ifnotready:logger.error(f"Deployment to {environment.value} not ready within timeout")self.deployment_status=DeploymentStatus.FAILEDreturnFalse# Run health checkshealth_checks_passed=self._run_health_checks(environment)ifnothealth_checks_passed:logger.error(f"Health checks failed for {environment.value}")self.deployment_status=DeploymentStatus.FAILEDreturnFalsedeployment_time=time.time()-start_timeself.deployment_metrics[environment.value]={"deployment_time":deployment_time,"status":"success","timestamp":datetime.utcnow().isoformat()}logger.info(f"Successfully deployed to {environment.value} in {deployment_time:.2f}s")self.deployment_status=DeploymentStatus.SUCCESSreturnTrueexceptExceptionase:logger.error(f"Error deploying to {environment.value}: {e}")self.deployment_status=DeploymentStatus.FAILEDreturnFalsedefswitch_traffic(self,from_env:Environment,to_env:Environment)->bool:"""Switch traffic from one environment to another"""try:logger.info(f"Switching traffic from {from_env.value} to {to_env.value}")# Update load balancer configurationsuccess=self.load_balancer.update_backend_servers(to_env.value)ifnotsuccess:logger.error(f"Failed to update load balancer for {to_env.value}")returnFalse# Verify traffic switchtraffic_switched=self._verify_traffic_switch(to_env)ifnottraffic_switched:logger.error(f"Traffic switch verification failed for {to_env.value}")returnFalselogger.info(f"Successfully switched traffic to {to_env.value}")returnTrueexceptExceptionase:logger.error(f"Error switching traffic: {e}")returnFalsedefrollback_deployment(self,from_env:Environment,to_env:Environment)->bool:"""Rollback deployment to previous environment"""try:logger.info(f"Rolling back from {from_env.value} to {to_env.value}")self.deployment_status=DeploymentStatus.ROLLBACK# Switch traffic backtraffic_switched=self.switch_traffic(from_env,to_env)ifnottraffic_switched:logger.error(f"Failed to rollback traffic to {to_env.value}")returnFalse# Scale down failed environmentself._scale_down_environment(from_env)logger.info(f"Successfully rolled back to {to_env.value}")returnTrueexceptExceptionase:logger.error(f"Error during rollback: {e}")returnFalsedef_create_deployment_manifest(self,environment:Environment)->Dict[str,Any]:"""Create Kubernetes deployment manifest"""manifest={"apiVersion":"apps/v1","kind":"Deployment","metadata":{"name":f"{self.config.application_name}-{environment.value}","labels":{"app":self.config.application_name,"environment":environment.value,"version":self.config.version}},"spec":{"replicas":self.config.replicas,"selector":{"matchLabels":{"app":self.config.application_name,"environment":environment.value}},"template":{"metadata":{"labels":{"app":self.config.application_name,"environment":environment.value,"version":self.config.version}},"spec":{"containers":[{"name":self.config.application_name,"image":f"{self.config.application_name}:{self.config.version}","ports":[{"containerPort":8000}],"resources":{"limits":{"cpu":self.config.cpu_limit,"memory":self.config.memory_limit},"requests":{"cpu":self.config.cpu_request,"memory":self.config.memory_request}},"livenessProbe":{"httpGet":{"path":self.config.health_check_path,"port":8000},"initialDelaySeconds":30,"periodSeconds":10},"readinessProbe":{"httpGet":{"path":self.config.readiness_check_path,"port":8000},"initialDelaySeconds":5,"periodSeconds":5}}]}}}}returnmanifestdef_apply_deployment(self,manifest:Dict[str,Any],environment:Environment)->bool:"""Apply deployment manifest to Kubernetes"""try:# In real implementation, this would use kubectl or Kubernetes APIlogger.info(f"Applying deployment manifest for {environment.value}")# Simulate deployment applicationtime.sleep(2)returnTrueexceptExceptionase:logger.error(f"Error applying deployment: {e}")returnFalsedef_wait_for_deployment_ready(self,environment:Environment)->bool:"""Wait for deployment to be ready"""start_time=time.time()timeout=self.config.deployment_timeoutwhiletime.time()-start_time<timeout:ifself.health_checker.check_environment_health(environment.value)["healthy"]:returnTruetime.sleep(10)returnFalsedef_run_health_checks(self,environment:Environment)->bool:"""Run comprehensive health checks"""health_checks=[self.health_checker.check_application_health,self.health_checker.check_database_connectivity,self.health_checker.check_external_services,self.health_checker.check_performance_metrics]forhealth_checkinhealth_checks:ifnothealth_check(environment.value):returnFalsereturnTruedef_verify_traffic_switch(self,environment:Environment)->bool:"""Verify that traffic has been switched to the new environment"""# Check if traffic is reaching the new environmentfor_inrange(10):# Check 10 timesifself.health_checker.check_environment_health(environment.value)["healthy"]:returnTruetime.sleep(5)returnFalsedef_scale_down_environment(self,environment:Environment)->None:"""Scale down the specified environment"""logger.info(f"Scaling down {environment.value} environment")# In real implementation, this would scale down the deploymentclassHealthChecker:"""Health check utilities for deployments"""def__init__(self):self.health_check_metrics={}defcheck_environment_health(self,environment:str)->Dict[str,Any]:"""Check overall health of an environment"""try:# Simulate health checkhealth_status={"environment":environment,"healthy":True,"timestamp":datetime.utcnow().isoformat(),"checks":{}}# Check application healthapp_health=self.check_application_health(environment)health_status["checks"]["application"]=app_health# Check database connectivitydb_health=self.check_database_connectivity(environment)health_status["checks"]["database"]=db_health# Overall health is healthy if all checks passhealth_status["healthy"]=app_healthanddb_healthreturnhealth_statusexceptExceptionase:logger.error(f"Error checking environment health: {e}")return{"environment":environment,"healthy":False,"error":str(e),"timestamp":datetime.utcnow().isoformat()}defcheck_application_health(self,environment:str)->bool:"""Check application health"""try:# Simulate health check requestresponse=requests.get(f"http://{environment}-app:8000/health",timeout=5)returnresponse.status_code==200exceptExceptionase:logger.error(f"Application health check failed for {environment}: {e}")returnFalsedefcheck_database_connectivity(self,environment:str)->bool:"""Check database connectivity"""try:# Simulate database connectivity check# In real implementation, this would check actual database connectionreturnTrueexceptExceptionase:logger.error(f"Database connectivity check failed for {environment}: {e}")returnFalsedefcheck_external_services(self,environment:str)->bool:"""Check external service dependencies"""try:# Simulate external service checks# In real implementation, this would check actual external servicesreturnTrueexceptExceptionase:logger.error(f"External services check failed for {environment}: {e}")returnFalsedefcheck_performance_metrics(self,environment:str)->bool:"""Check performance metrics"""try:# Simulate performance metrics check# In real implementation, this would check actual performance metricsreturnTrueexceptExceptionase:logger.error(f"Performance metrics check failed for {environment}: {e}")returnFalseclassLoadBalancer:"""Load balancer management"""def__init__(self):self.backend_servers={}self.load_balancer_metrics={}defupdate_backend_servers(self,environment:str)->bool:"""Update load balancer backend servers"""try:logger.info(f"Updating load balancer backend servers to {environment}")# In real implementation, this would update actual load balancer configurationself.backend_servers["active"]=environmentreturnTrueexceptExceptionase:logger.error(f"Error updating load balancer: {e}")returnFalsedefget_backend_servers(self)->Dict[str,str]:"""Get current backend server configuration"""returnself.backend_servers.copy()classCanaryDeployer:"""Canary deployment orchestrator"""def__init__(self,config:DeploymentConfig):self.config=configself.canary_percentage=0self.canary_metrics={}self.monitoring_duration=300# 5 minutesdefdeploy_canary(self,canary_percentage:int=10)->bool:"""Deploy canary version"""try:self.canary_percentage=canary_percentagelogger.info(f"Starting canary deployment with {canary_percentage}% traffic")# Deploy canary versioncanary_deployed=self._deploy_canary_version()ifnotcanary_deployed:returnFalse# Route percentage of traffic to canarytraffic_routed=self._route_canary_traffic(canary_percentage)ifnottraffic_routed:returnFalse# Monitor canary performancemonitoring_success=self._monitor_canary_performance()ifnotmonitoring_success:logger.warning("Canary monitoring detected issues")returnFalselogger.info("Canary deployment successful")returnTrueexceptExceptionase:logger.error(f"Error in canary deployment: {e}")returnFalsedefpromote_canary(self)->bool:"""Promote canary to full deployment"""try:logger.info("Promoting canary to full deployment")# Route 100% traffic to canarytraffic_routed=self._route_canary_traffic(100)ifnottraffic_routed:returnFalse# Scale up canary environmentscaled_up=self._scale_up_canary()ifnotscaled_up:returnFalse# Scale down old environmentself._scale_down_old_environment()logger.info("Canary successfully promoted")returnTrueexceptExceptionase:logger.error(f"Error promoting canary: {e}")returnFalsedefrollback_canary(self)->bool:"""Rollback canary deployment"""try:logger.info("Rolling back canary deployment")# Route traffic back to stable versiontraffic_routed=self._route_canary_traffic(0)ifnottraffic_routed:returnFalse# Scale down canary environmentself._scale_down_canary()logger.info("Canary rollback successful")returnTrueexceptExceptionase:logger.error(f"Error rolling back canary: {e}")returnFalsedef_deploy_canary_version(self)->bool:"""Deploy canary version"""# Simulate canary deploymenttime.sleep(2)returnTruedef_route_canary_traffic(self,percentage:int)->bool:"""Route traffic to canary"""logger.info(f"Routing {percentage}% traffic to canary")# Simulate traffic routingtime.sleep(1)returnTruedef_monitor_canary_performance(self)->bool:"""Monitor canary performance"""logger.info(f"Monitoring canary performance for {self.monitoring_duration} seconds")start_time=time.time()whiletime.time()-start_time<self.monitoring_duration:# Simulate performance monitoringifnotself._check_canary_metrics():returnFalsetime.sleep(30)returnTruedef_check_canary_metrics(self)->bool:"""Check canary performance metrics"""# Simulate metrics checkreturnTruedef_scale_up_canary(self)->bool:"""Scale up canary environment"""logger.info("Scaling up canary environment")returnTruedef_scale_down_canary(self)->bool:"""Scale down canary environment"""logger.info("Scaling down canary environment")returnTruedef_scale_down_old_environment(self)->bool:"""Scale down old environment"""logger.info("Scaling down old environment")returnTrue# Usage examplesdefexample_blue_green_deployment():"""Example blue-green deployment usage"""# Create deployment configurationconfig=DeploymentConfig(application_name="my-app",version="v1.2.0",environment="production",replicas=3)# Create blue-green deployerdeployer=BlueGreenDeployer(config)# Determine current environmentcurrent_env=deployer.determine_current_environment()print(f"Current environment: {current_env.value}")# Determine target environmenttarget_env=Environment.GREENifcurrent_env==Environment.BLUEelseEnvironment.BLUE# Deploy to target environmentdeployment_success=deployer.deploy_to_environment(target_env)print(f"Deployment to {target_env.value}: {deployment_success}")ifdeployment_success:# Switch traffictraffic_switched=deployer.switch_traffic(current_env,target_env)print(f"Traffic switch: {traffic_switched}")ifnottraffic_switched:# Rollback if traffic switch failedrollback_success=deployer.rollback_deployment(target_env,current_env)print(f"Rollback: {rollback_success}")# Canary deployment examplecanary_deployer=CanaryDeployer(config)# Deploy canarycanary_success=canary_deployer.deploy_canary(canary_percentage=10)print(f"Canary deployment: {canary_success}")ifcanary_success:# Promote canarypromote_success=canary_deployer.promote_canary()print(f"Canary promotion: {promote_success}")