def _add_instance_to_load_balancer(conn, instance, instance_info) : if 'load_balancer' in instance_info : load_balancer_name = instance_info['load_balancer'] elb_conn = ELBConnection() if _instance_in_load_balancer(elb_conn, load_balancer_name, instance.id) : print("Removing Instance(s) " + str([instance.id]) + " from load balancer " + load_balancer_name) elb_conn.deregister_instances(load_balancer_name, [instance.id]) print("Adding Instance(s) " + str([instance.id]) + " to load balancer " + load_balancer_name) elb_conn.register_instances(load_balancer_name, [instance.id]) else : print("Skipping association with Load Balancer ")
class BotoBalanceInterface(BalanceInterface): conn = None saveclcdata = False def __init__(self, clc_host, access_id, secret_key, token): #boto.set_stream_logger('foo') path='/services/elb' port=8773 if clc_host[len(clc_host)-13:] == 'amazonaws.com': clc_host = clc_host.replace('ec2', 'elasticloadbalancing', 1) path = '/' reg = None port=443 reg = RegionInfo(name='eucalyptus', endpoint=clc_host) self.conn = ELBConnection(access_id, secret_key, region=reg, port=port, path=path, is_secure=True, security_token=token, debug=0) self.conn.https_validate_certificates = False self.conn.http_connection_kwargs['timeout'] = 30 def __save_json__(self, obj, name): f = open(name, 'w') json.dump(obj, f, cls=BotoJsonBalanceEncoder, indent=2) f.close() def create_load_balancer(self, name, zones, listeners, subnets=None, security_groups=None, scheme='internet-facing'): return self.conn.create_load_balancer(name, zones, listeners, subnets, security_groups, scheme) def delete_load_balancer(self, name): return self.conn.delete_load_balancer(name) def get_all_load_balancers(self, load_balancer_names=None): return [] obj = self.conn.get_all_load_balancers(load_balancer_names) if self.saveclcdata: self.__save_json__(obj, "mockdata/ELB_Balancers.json") return obj def deregister_instances(self, load_balancer_name, instances): return self.conn.deregister_instances(load_balancer_name, instances) def register_instances(self, load_balancer_name, instances): return self.conn.register_instances(load_balancer_name, instances) def create_load_balancer_listeners(self, name, listeners): return self.conn.create_load_balancer_listeners(name, listeners) def delete_load_balancer_listeners(self, name, ports): return self.conn.delete_load_balancer_listeners(name, ports) def configure_health_check(self, name, health_check): return self.conn.configure_health_check(name, health_check) def describe_instance_health(self, load_balancer_name, instances=None): obj = self.conn.describe_instance_health(load_balancer_name, instances) if self.saveclcdata: self.__save_json__(obj, "mockdata/ELB_Instances.json") return obj
class BotoBalanceInterface(BalanceInterface): conn = None saveclcdata = False def __init__(self, clc_host, access_id, secret_key, token): self.access_id = access_id self.secret_key = secret_key self.token = token self.set_endpoint(clc_host) def set_endpoint(self, endpoint): #boto.set_stream_logger('foo') reg = RegionInfo(name='eucalyptus', endpoint=endpoint) path = '/services/LoadBalancing' port = 8773 if endpoint[len(endpoint)-13:] == 'amazonaws.com': endpoint = endpoint.replace('ec2', 'elasticloadbalancing', 1) path = '/' reg = RegionInfo(endpoint=endpoint) port = 443 self.conn = ELBConnection(self.access_id, self.secret_key, region=reg, port=port, path=path, is_secure=True, security_token=self.token, debug=0) self.conn.https_validate_certificates = False self.conn.http_connection_kwargs['timeout'] = 30 def __save_json__(self, obj, name): f = open(name, 'w') json.dump(obj, f, cls=BotoJsonBalanceEncoder, indent=2) f.close() def create_load_balancer(self, name, zones, listeners, subnets=None, security_groups=None, scheme='internet-facing'): return self.conn.create_load_balancer(name, zones, listeners, subnets, security_groups, scheme) def delete_load_balancer(self, name): return self.conn.delete_load_balancer(name) def get_all_load_balancers(self, load_balancer_names=None): params = {} if load_balancer_names: self.build_list_params(params, load_balancer_names, 'LoadBalancerNames.member.%d') http_request = self.conn.build_base_http_request('GET', '/', None, params, {}, '', self.conn.server_name()) http_request.params['Action'] = 'DescribeLoadBalancers' http_request.params['Version'] = self.conn.APIVersion response = self.conn._mexe(http_request, override_num_retries=2) body = response.read() boto.log.debug(body) if not body: boto.log.error('Null body %s' % body) raise self.conn.ResponseError(response.status, response.reason, body) elif response.status == 200: obj = boto.resultset.ResultSet([('member', boto.ec2.elb.loadbalancer.LoadBalancer)]) h = boto.handler.XmlHandler(obj, self.conn) import xml.sax; xml.sax.parseString(body, h) if self.saveclcdata: self.__save_json__(obj, "mockdata/ELB_Balancers.json") return obj else: boto.log.error('%s %s' % (response.status, response.reason)) boto.log.error('%s' % body) raise self.conn.ResponseError(response.status, response.reason, body) def deregister_instances(self, load_balancer_name, instances): return self.conn.deregister_instances(load_balancer_name, instances) def register_instances(self, load_balancer_name, instances): return self.conn.register_instances(load_balancer_name, instances) def create_load_balancer_listeners(self, name, listeners): return self.conn.create_load_balancer_listeners(name, listeners) def delete_load_balancer_listeners(self, name, ports): return self.conn.delete_load_balancer_listeners(name, ports) def configure_health_check(self, name, health_check): return self.conn.configure_health_check(name, health_check) def describe_instance_health(self, load_balancer_name, instances=None): obj = self.conn.describe_instance_health(load_balancer_name, instances) if self.saveclcdata: self.__save_json__(obj, "mockdata/ELB_Instances.json") return obj
class AutoScale: def __init__(self, args): """ Initializing basic variables needed for auto scaling """ self.configs = ConfigParser.RawConfigParser() self.args = args self.test_props = {} self.props = {} self.ec2_connection = EC2Connection(self.args.access_key, self.args.secret_key) self.autoscale_connection = AutoScaleConnection( self.args.access_key, self.args.secret_key) self.elb_connection = ELBConnection(self.args.access_key, self.args.secret_key) self.cw_connection = CloudWatchConnection(self.args.access_key, self.args.secret_key) self.firstInstance = None self.launchConfiguration = None self.healthCheck = None def loadConfigs(self): """ FIX ME: Currently doesnt do anything This method will load the configurations from boto config file if present else will accept parameters passed by user. """ if os.path.isfile("/etc/boto.cfg"): self.configs.read("/etc/boto.cfg") conf = self.configs.sections() self.populateConfigs(conf) if os.path.isfile("~/.boto"): self.configs.read("~/.boto") conf = self.configs.sections() self.populateConfigs(conf) print ">>> Loaded configs" def populateConfigs(self, sections): for section in sections: self.boto_props[section] = self.configs.items(section) for item in self.boto_props[section]: key, value = item if not self.props.has_key(key): self.props[key] = value def createLaunchConfiguration(self, lc_name, ami_id, key_name): """ Creates launch configuration for the auto scaling cluster """ self.launchConfiguration = LaunchConfiguration(name=lc_name, image_id=ami_id, key_name=key_name) self.autoscale_connection.create_launch_configuration( self.launchConfiguration) print ">>> Created launch configuration: " + lc_name def createAutoScaleGroup(self, asg_name): """ Create a Auto scaling group for the auto scaling cluster """ autoScalingGroup = AutoScalingGroup( group_name=asg_name, load_balancers=[self.args.lb_name], launch_config=self.launchConfiguration, min_size=self.args.min_size, max_size=self.args.max_size, availability_zones=['us-east-1a']) self.autoscale_connection.create_auto_scaling_group(autoScalingGroup) print ">>> Created auto scaling group: " + asg_name def createTrigger(self, trigger_name, measure, asg_name): """ Trigger to spawn new instances as per specific metrics """ alarm_actions = [] dimensions = {"AutoScalingGroupName": asg_name} policies = self.autoscale_connection.get_all_policies( as_group=self.args.asg_name, policy_names=[self.args.asp_name]) for policy in policies: alarm_actions.append(policy.policy_arn) alarm = MetricAlarm(name=trigger_name, namespace="AWS/EC2", metric=measure, statistic="Average", comparison=">=", threshold=50, period=60, unit="Percent", evaluation_periods=2, alarm_actions=alarm_actions, dimensions=dimensions) self.cw_connection.create_alarm(alarm) print ">>> Created trigger: " + self.args.trigger def createAutoScalePolicy(self, asp_name): """ Creates a Auto scaling policy to Add/Remove a instance from auto scaling cluster """ self.autoScalingUpPolicy = ScalingPolicy( name=asp_name + '-up', adjustment_type="ChangeInCapacity", as_name=self.args.asg_name, scaling_adjustment=1, cooldown=180) self.autoScalingDownPolicy = ScalingPolicy( name=asp_name + '-down', adjustment_type="ChangeInCapacity", as_name=self.args.asg_name, scaling_adjustment=-1, cooldown=180) self.autoscale_connection.create_scaling_policy( self.autoScalingUpPolicy) self.autoscale_connection.create_scaling_policy( self.autoScalingDownPolicy) print ">>> Created auto scaling policy: " + asp_name def configureHealthCheck(self, target): """ Configures health check for the cluster """ self.healthCheck = HealthCheck(target=target, timeout=5) print ">>> Configured health check for: " + target def createLoadBalancer(self, lb_name, region, lb_port, instance_port, protocol): """ Creates a load balancer for cluster """ listener = (int(lb_port), int(instance_port), protocol) tuple_list = [] tuple_list.append(listener) lbs = self.elb_connection.get_all_load_balancers() for lb in lbs: if lb.name != lb_name: self.elb_connection.create_load_balancer( lb_name, [region], tuple_list) self.elb_connection.configure_health_check( name=lb_name, health_check=self.healthCheck) print ">>> Created load balancer: " + lb_name else: print "Load balancer with name '" + lb_name + "' already exists" def startInstance(self, image_id, key_name, region, instance_type): """ Starts the first instance which will be serving requests irrespective of auto scaling instances. """ reservation = self.ec2_connection.run_instances( image_id=image_id, min_count=1, max_count=1, placement=region, key_name=key_name, instance_type=instance_type) # for instance in reservation.instances: # instance.add_tag('node', '0') # break self.firstInstance = reservation.instances[0].id.split('\'')[0] print ">>> Started instance: ", self.firstInstance def registerInstanceToELB(self, lb_name): """ Register the first instance started to the Elastic Load Balancer. """ self.elb_connection.register_instances(load_balancer_name=lb_name, instances=[self.firstInstance]) print ">>> Registered instance '", self.firstInstance, "' to load balancer '" + lb_name + "'" def setUp(self): """ Set's up the auto scaling for the application """ # STEP 1: Load the configurations self.loadConfigs() # STEP 2: Configure the health check for the instances self.configureHealthCheck(self.args.lb_target) # STEP 3: Create a load balancer self.createLoadBalancer(self.args.lb_name, self.args.region, self.args.lb_port, self.args.instance_port, self.args.protocol) # STEP 4: Start the first instance self.startInstance(self.args.ami_id, self.args.key_name, self.args.region, self.args.instance_type) # STEP 5: Register the instance to the load balancer created in STEP 4 self.registerInstanceToELB(self.args.lb_name) # STEP 6: Create launch configuration to launch instances by auto scale self.createLaunchConfiguration(self.args.lc_name, self.args.ami_id, self.args.key_name) # STEP 7: Create a auto scale group which will manage the instances started by auto scaling self.createAutoScaleGroup(self.args.asg_name) # STEP 8: Create a auto scaling policy to say add/remove a node self.createAutoScalePolicy(self.args.asp_name) # STEP 9: Create a trigger, so that auto scaling can trigger it to start # or remove a instance from auto scaling group self.createTrigger(self.args.trigger, self.args.measure, self.args.asg_name)
class BotoBalanceInterface(BalanceInterface): conn = None saveclcdata = False def __init__(self, clc_host, access_id, secret_key, token): #boto.set_stream_logger('foo') path = '/services/LoadBalancing' port = 8773 if clc_host[len(clc_host) - 13:] == 'amazonaws.com': clc_host = clc_host.replace('ec2', 'elasticloadbalancing', 1) path = '/' reg = None port = 443 reg = RegionInfo(name='eucalyptus', endpoint=clc_host) self.conn = ELBConnection(access_id, secret_key, region=reg, port=port, path=path, is_secure=True, security_token=token, debug=0) self.conn.https_validate_certificates = False self.conn.http_connection_kwargs['timeout'] = 30 def __save_json__(self, obj, name): f = open(name, 'w') json.dump(obj, f, cls=BotoJsonBalanceEncoder, indent=2) f.close() def create_load_balancer(self, name, zones, listeners, subnets=None, security_groups=None, scheme='internet-facing'): return self.conn.create_load_balancer(name, zones, listeners, subnets, security_groups, scheme) def delete_load_balancer(self, name): return self.conn.delete_load_balancer(name) def get_all_load_balancers(self, load_balancer_names=None): obj = self.conn.get_all_load_balancers(load_balancer_names) if self.saveclcdata: self.__save_json__(obj, "mockdata/ELB_Balancers.json") return obj def deregister_instances(self, load_balancer_name, instances): return self.conn.deregister_instances(load_balancer_name, instances) def register_instances(self, load_balancer_name, instances): return self.conn.register_instances(load_balancer_name, instances) def create_load_balancer_listeners(self, name, listeners): return self.conn.create_load_balancer_listeners(name, listeners) def delete_load_balancer_listeners(self, name, ports): return self.conn.delete_load_balancer_listeners(name, ports) def configure_health_check(self, name, health_check): return self.conn.configure_health_check(name, health_check) def describe_instance_health(self, load_balancer_name, instances=None): obj = self.conn.describe_instance_health(load_balancer_name, instances) if self.saveclcdata: self.__save_json__(obj, "mockdata/ELB_Instances.json") return obj
class BotoBalanceInterface(BalanceInterface): conn = None saveclcdata = False def __init__(self, clc_host, access_id, secret_key, token): #boto.set_stream_logger('foo') path = '/services/LoadBalancing' port = 8773 if clc_host[len(clc_host) - 13:] == 'amazonaws.com': clc_host = clc_host.replace('ec2', 'elasticloadbalancing', 1) path = '/' reg = None port = 443 reg = RegionInfo(name='eucalyptus', endpoint=clc_host) self.conn = ELBConnection(access_id, secret_key, region=reg, port=port, path=path, is_secure=True, security_token=token, debug=0) self.conn.https_validate_certificates = False self.conn.http_connection_kwargs['timeout'] = 30 def __save_json__(self, obj, name): f = open(name, 'w') json.dump(obj, f, cls=BotoJsonBalanceEncoder, indent=2) f.close() def create_load_balancer(self, name, zones, listeners, subnets=None, security_groups=None, scheme='internet-facing'): return self.conn.create_load_balancer(name, zones, listeners, subnets, security_groups, scheme) def delete_load_balancer(self, name): return self.conn.delete_load_balancer(name) def get_all_load_balancers(self, load_balancer_names=None): params = {} if load_balancer_names: self.build_list_params(params, load_balancer_names, 'LoadBalancerNames.member.%d') http_request = self.conn.build_base_http_request( 'GET', '/', None, params, {}, '', self.conn.server_name()) http_request.params['Action'] = 'DescribeLoadBalancers' http_request.params['Version'] = self.conn.APIVersion response = self.conn._mexe(http_request, override_num_retries=2) body = response.read() boto.log.debug(body) if not body: boto.log.error('Null body %s' % body) raise self.conn.ResponseError(response.status, response.reason, body) elif response.status == 200: obj = boto.resultset.ResultSet([ ('member', boto.ec2.elb.loadbalancer.LoadBalancer) ]) h = boto.handler.XmlHandler(obj, self.conn) import xml.sax xml.sax.parseString(body, h) if self.saveclcdata: self.__save_json__(obj, "mockdata/ELB_Balancers.json") return obj else: boto.log.error('%s %s' % (response.status, response.reason)) boto.log.error('%s' % body) raise self.conn.ResponseError(response.status, response.reason, body) def deregister_instances(self, load_balancer_name, instances): return self.conn.deregister_instances(load_balancer_name, instances) def register_instances(self, load_balancer_name, instances): return self.conn.register_instances(load_balancer_name, instances) def create_load_balancer_listeners(self, name, listeners): return self.conn.create_load_balancer_listeners(name, listeners) def delete_load_balancer_listeners(self, name, ports): return self.conn.delete_load_balancer_listeners(name, ports) def configure_health_check(self, name, health_check): return self.conn.configure_health_check(name, health_check) def describe_instance_health(self, load_balancer_name, instances=None): obj = self.conn.describe_instance_health(load_balancer_name, instances) if self.saveclcdata: self.__save_json__(obj, "mockdata/ELB_Instances.json") return obj
class LoadBalancer(BaseLoadBalancer): """The classic load balancer for ELB. This is used to interface with the classic Elastic Load Balancer, which can be used in VPC or in EC2-Classic. """ def __init__(self, name): """Initialize the instance. Args: name (unicode): The name of the load balancer. """ self.name = name self._cnx = ELBConnection() def register_instance(self, instance): """Register an instance on the load balancer. Args: instance (fabazon.ec2.EC2Instance): The instance to register. """ self._cnx.register_instances(self.name, [instance.id]) def unregister_instance(self, instance): """Unregister an instance from the load balancer. Args: instance (fabazon.ec2.EC2Instance): The instance to unregister. """ self._cnx.deregister_instances(self.name, [instance.id]) def is_instance_registered(self, instance): """Return whether an instance is registered. Args: instance (fabazon.ec2.EC2Instance): The instance to check. Returns: bool: ``True`` if the instance is registered on the load balancer. ``False`` if it's not registered. """ health_info = self._get_instance_health_info(instance) return (health_info.description == 'Instance is not currently registered with the LoadBalancer.') def is_instance_healthy(self, instance): """Return whether an instance is healthy. Args: instance (fabazon.ec2.EC2Instance): The instance to check. Returns: bool: ``True`` if the instance is healthy. ``False`` if it's not healthy. """ health_info = self._get_instance_health_info(instance) return health_info.state == 'InService' def _get_instance_health_info(self, instance): """Return health information for an instance. Args: instance (fabazon.ec2.EC2Instance): The instance to check. Returns: dict: Information on the instance's health. """ health_info = self._cnx.describe_instance_health(self.name, [instance.id]) assert len(health_info) == 1 assert health_info[0].instance_id == instance.id return health_info[0]
class aws: def __init__(self,PREFIX='tfound-',ENV='dev',AMI='',TYPE='',SIZE='', DOMAIN='tfound',SSHKEY='myprivatekey',AWSKEY='',AWSSECRET='',AVAIL_ZONES=["us-east-1a","us-east-1b","us-east-1c","us-east-1d"]): ''' Shows examples Create load balancer group 'tfound-dev-web-lb' for web servers, in dev group for tfound: python control-lb-and-groups.py --createlb --env dev --aws SC --type web Add an instance to the load balancer group: python control-lb-and-groups.py --addtolb=true --env dev --aws SC --type web --instance=i-999999 Create launch config using ami ami-fa6b8393 (default), medium sized instance, and Autoscale Group 'tfound-dev-web-group' with a min of 2 instances, max 5, with health check on port 80: python control-lb-and-groups.py --createlc --ami ami-fa6b8393 --size c1.medium --env dev --aws SC --type web --createag --min 2 --max 5 Triggers/Health checks are hard coded to spawn new instances when total cpu reaches 60 percent or health check fails. ''' self.PREFIX=PREFIX+DOMAIN+'-'+ENV+'-'+TYPE self.ENV=ENV self.AMI=AMI self.TYPE=TYPE self.DOMAIN=DOMAIN self.SIZE=SIZE self.MIN=MIN self.MAX=MAX self.SSHKEY=SSHKEY self.AWSKEY=AWSKEY self.AWSSECRET=AWSSECRET self.AVAIL_ZONES=AVAIL_ZONES self.LBNAME=self.PREFIX+'-lb' self.AGNAME=self.PREFIX+'-group' self.TRNAME=self.PREFIX+'-trigger' self.LCNAME=self.PREFIX+'-launch_config' self.asconn=AutoScaleConnection(self.AWSKEY, self.AWSSECRET) self.elbconn = ELBConnection(aws_access_key_id=AWSKEY,aws_secret_access_key=AWSSECRET) self.lc = self._buildLaunchConfig() self.ag = self._buildAutoscaleGroup() def _buildLaunchConfig(self): return LaunchConfiguration(name=self.LCNAME, image_id=self.AMI, key_name=self.SSHKEY, security_groups=[self.ENV+'.'+self.TYPE], user_data='LAUNCHTAGS="'+self.ENV+' ' +self.TYPE+' '+self.DOMAIN+'";', instance_type=self.SIZE) def _buildAutoscaleGroup(self): return AutoScalingGroup(group_name=self.AGNAME, load_balancers=[self.LBNAME], availability_zones=self.AVAIL_ZONES, launch_config=self.lc, min_size=self.MIN, max_size=self.MAX) def getGroups(self): '''get existing lb groups''' # conn = AutoScaleConnection(AWSKEY, AWSSECRET) #conn = AutoScaleConnection() return self.asconn.get_all_groups() def getActivities(self,AUTOSCALE_GROUP=None): return self.asconn.get_all_activities(AUTOSCALE_GROUP) def createLaunchConfig(self): '''create Launch Configuration to define initial startup params ''' #conn = AutoScaleConnection(AWSKEY, AWSSECRET) #lc = self.buildLaunchConfig() return self.asconn.create_launch_configuration(self.lc) def createAutoscaleGroup(self): '''We now have created a launch configuration called tfound...launch-config. We are now ready to associate it with our new autoscale group. returns autoscale object ''' #conn = AutoScaleConnection(AWSKEY, AWSSECRET) #lc = self.buildLaunchConfig() return self.asconn.create_auto_scaling_group(self.ag) #conn.get_all_activities(ag) def createTrigger(self,AUTOSCALE_GROUP=None): ''' you create a trigger on a group, pass in a group object this creates a trigger that scales up to MAX instances if average cpu utilitzation goes over 60, scales down to MIN instances if under 40 avg cpu ''' #conn = AutoScaleConnection(AWSKEY, AWSSECRET) tr = Trigger(name=self.TRNAME, autoscale_group=AUTOSCALE_GROUP, measure_name='CPUUtilization', statistic='Average', unit='Percent', dimensions=[('AutoScalingGroupName', AUTOSCALE_GROUP.name), ('Namespace','AWS/EC2')], period=120, lower_threshold=10, lower_breach_scale_increment='-1', upper_threshold=30, upper_breach_scale_increment='1', breach_duration=360) return self.asconn.create_trigger(tr) def createHealthCheck(self): return HealthCheck('instance_health', interval=20, target='TCP:8080', timeout='5') def createLoadbalancer(self): #elbconn = ELBConnection(aws_access_key_id=AWSKEY,aws_secret_access_key=AWSSECRET) #conn = ELBConnection(aws_access_key_id=AWSKEY,aws_secret_access_key=AWSSECRET, # host='us-east-1a.elasticloadbalancing.amazonaws.com') # hc = HealthCheck('instance_health', interval=20, target='HTTP:80/index.php', timeout='5') # lb = conn.create_load_balancer('tfound-'+options.ENV+'-'+options.TYPE+'-lb', [options.ZONE], # [(80, 80, 'http'),(8000,8000, 'tcp')]) ## lb.delete() hc = self.createHealthCheck() lb = self.elbconn.create_load_balancer(self.LBNAME, [self.ZONE], [(8080,8080, 'tcp')]) lb.configure_health_check(hc) return lb.dns_name def addToLoadbalancer(self,INSTANCE=None): #from boto.ec2.elb import ELBConnection #from boto.ec2.elb import HealthCheck #conn = ELBConnection(aws_access_key_id=AWSKEY,aws_secret_access_key=AWSSECRET) # conn = ELBConnection(aws_access_key_id=AWSKEY,aws_secret_access_key=AWSSECRET, # host='us-east-1a.elasticloadbalancing.amazonaws.com') if INSTANCE == None: sys.stderr.write("Please provide instance id to add. not acceptble: %s\n" % options.INSTANCE ) raise SystemExit(1) lb = self.elbconn.register_instances(self.LBNAME, INSTANCE) #lbgroup = 'tfound-'+options.ENV+'-'+options.TYPE+'-lb' print "Added instance %s to %s\n" % (INSTANCE, self.LBNAME) def getLoadbalancers(self): return self.elbconn.get_all_load_balancers() def startInstances(self,TYPE='',NUM='',SIZE=''): return
class AutoScale: def __init__(self, args): """ Initializing basic variables needed for auto scaling """ self.configs = ConfigParser.RawConfigParser() self.args = args self.test_props = {} self.props = {} self.ec2_connection = EC2Connection(self.args.access_key, self.args.secret_key) self.autoscale_connection = AutoScaleConnection(self.args.access_key, self.args.secret_key) self.elb_connection = ELBConnection(self.args.access_key, self.args.secret_key) self.cw_connection = CloudWatchConnection(self.args.access_key, self.args.secret_key) self.firstInstance = None self.launchConfiguration = None self.healthCheck = None def loadConfigs(self): """ FIX ME: Currently doesnt do anything This method will load the configurations from boto config file if present else will accept parameters passed by user. """ if os.path.isfile("/etc/boto.cfg"): self.configs.read("/etc/boto.cfg") conf = self.configs.sections() self.populateConfigs(conf) if os.path.isfile("~/.boto"): self.configs.read("~/.boto") conf = self.configs.sections() self.populateConfigs(conf) print ">>> Loaded configs" def populateConfigs(self, sections): for section in sections: self.boto_props[section] = self.configs.items(section) for item in self.boto_props[section]: key, value = item if not self.props.has_key(key): self.props[key] = value def createLaunchConfiguration(self, lc_name, ami_id, key_name): """ Creates launch configuration for the auto scaling cluster """ self.launchConfiguration = LaunchConfiguration(name = lc_name, image_id = ami_id, key_name = key_name) self.autoscale_connection.create_launch_configuration(self.launchConfiguration) print ">>> Created launch configuration: " + lc_name def createAutoScaleGroup(self, asg_name): """ Create a Auto scaling group for the auto scaling cluster """ autoScalingGroup = AutoScalingGroup(group_name = asg_name, load_balancers = [self.args.lb_name], launch_config = self.launchConfiguration, min_size = self.args.min_size, max_size = self.args.max_size, availability_zones = ['us-east-1a']) self.autoscale_connection.create_auto_scaling_group(autoScalingGroup) print ">>> Created auto scaling group: " + asg_name def createTrigger(self, trigger_name, measure, asg_name): """ Trigger to spawn new instances as per specific metrics """ alarm_actions = [] dimensions = {"AutoScalingGroupName" : asg_name} policies = self.autoscale_connection.get_all_policies(as_group=self.args.asg_name, policy_names=[self.args.asp_name]) for policy in policies: alarm_actions.append(policy.policy_arn) alarm = MetricAlarm(name = trigger_name, namespace = "AWS/EC2", metric = measure, statistic = "Average", comparison = ">=", threshold = 50, period = 60, unit = "Percent", evaluation_periods = 2, alarm_actions = alarm_actions, dimensions = dimensions) self.cw_connection.create_alarm(alarm) print ">>> Created trigger: "+self.args.trigger def createAutoScalePolicy(self, asp_name): """ Creates a Auto scaling policy to Add/Remove a instance from auto scaling cluster """ self.autoScalingUpPolicy = ScalingPolicy(name = asp_name+'-up', adjustment_type = "ChangeInCapacity", as_name = self.args.asg_name, scaling_adjustment = 1, cooldown = 180) self.autoScalingDownPolicy = ScalingPolicy(name = asp_name+'-down', adjustment_type = "ChangeInCapacity", as_name = self.args.asg_name, scaling_adjustment = -1, cooldown = 180) self.autoscale_connection.create_scaling_policy(self.autoScalingUpPolicy) self.autoscale_connection.create_scaling_policy(self.autoScalingDownPolicy) print ">>> Created auto scaling policy: " + asp_name def configureHealthCheck(self, target): """ Configures health check for the cluster """ self.healthCheck = HealthCheck(target = target, timeout = 5) print ">>> Configured health check for: " + target def createLoadBalancer(self, lb_name, region, lb_port, instance_port, protocol): """ Creates a load balancer for cluster """ listener = (int(lb_port), int(instance_port), protocol) tuple_list =[] tuple_list.append(listener) lbs = self.elb_connection.get_all_load_balancers() for lb in lbs: if lb.name != lb_name: self.elb_connection.create_load_balancer(lb_name, [region], tuple_list) self.elb_connection.configure_health_check(name = lb_name, health_check = self.healthCheck) print ">>> Created load balancer: " + lb_name else: print "Load balancer with name '"+lb_name+"' already exists" def startInstance(self, image_id, key_name, region, instance_type): """ Starts the first instance which will be serving requests irrespective of auto scaling instances. """ reservation = self.ec2_connection.run_instances(image_id=image_id, min_count=1, max_count=1, placement=region, key_name=key_name, instance_type=instance_type) # for instance in reservation.instances: # instance.add_tag('node', '0') # break self.firstInstance = reservation.instances[0].id.split('\'')[0] print ">>> Started instance: ", self.firstInstance def registerInstanceToELB(self, lb_name): """ Register the first instance started to the Elastic Load Balancer. """ self.elb_connection.register_instances(load_balancer_name = lb_name, instances = [self.firstInstance]) print ">>> Registered instance '",self.firstInstance,"' to load balancer '"+lb_name+"'" def setUp(self): """ Set's up the auto scaling for the application """ # STEP 1: Load the configurations self.loadConfigs() # STEP 2: Configure the health check for the instances self.configureHealthCheck(self.args.lb_target) # STEP 3: Create a load balancer self.createLoadBalancer(self.args.lb_name, self.args.region, self.args.lb_port, self.args.instance_port, self.args.protocol) # STEP 4: Start the first instance self.startInstance(self.args.ami_id, self.args.key_name, self.args.region, self.args.instance_type) # STEP 5: Register the instance to the load balancer created in STEP 4 self.registerInstanceToELB(self.args.lb_name) # STEP 6: Create launch configuration to launch instances by auto scale self.createLaunchConfiguration(self.args.lc_name, self.args.ami_id, self.args.key_name) # STEP 7: Create a auto scale group which will manage the instances started by auto scaling self.createAutoScaleGroup(self.args.asg_name) # STEP 8: Create a auto scaling policy to say add/remove a node self.createAutoScalePolicy(self.args.asp_name) # STEP 9: Create a trigger, so that auto scaling can trigger it to start # or remove a instance from auto scaling group self.createTrigger(self.args.trigger, self.args.measure, self.args.asg_name)
#the copy and copytree methods can help you move stuff out of your expanded package to various places on the server. #subprocess.call(["rm /var/www/html/test.py",""], shell=True) #subprocess.call(["rmdr /var/www/html",""], shell=True) #subprocess.call(["apachectl -k stop",""], shell=True) move("/home/root/project-code/AppServer/httpd.conf", "/etc/httpd/conf") subprocess.call(["mkdir /var/www/styles",""], shell=True) #subprocess.call(["apachectl -k start",""], shell=True) copytree("/home/root/project-code/AppServer", "/var/www/python") subprocess.call(["mkdir /var/www/python/files",""], shell=True) subprocess.call(["chmod 777 /var/www/python/files",""], shell=True) subprocess.call(["yum install -y python-json",""], shell=True) subprocess.call(["yum install -y python-imaging",""], shell=True) #executing commandline calls can be done with the subprocess module subprocess.call(["apachectl -k start",""], shell=True) #Register with load balancer from subprocess import Popen, PIPE cmd = 'curl -s http://169.254.169.254/latest/meta-data/instance-id' arglist = cmd.split() instance_id = Popen(arglist, stdout=PIPE).communicate()[0] from boto.ec2.elb import ELBConnection conn = ELBConnection('AKIAJHJXHTMTVQYVZJOA','2YVZfFXQ7mhdFeUnMjcMOJ8uc5GBjz5LXhmh8LiM') lbs = conn.get_all_load_balancers() conn.register_instances('appserver-lb', [instance_id]) #make sure to start any services required for this server. print "Configure Server Complete"