Last active
February 14, 2022 04:35
-
-
Save chiradeep/6877402a5705c84dd2ac to your computer and use it in GitHub Desktop.
Revisions
-
chiradeep revised this gist
Dec 21, 2015 . 1 changed file with 46 additions and 33 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,61 +1,74 @@ import argparse import boto3 import datetime from dateutil.tz import tzutc def is_in_autoscale_group(region, instance_id): asg = boto3.client('autoscaling', region_name=region) instances = \ asg.describe_auto_scaling_instances(InstanceIds=[instance_id]) instance_status = instances['AutoScalingInstances'] if instance_status: print "Instance %s is in autoscale group %s" \ % (instance_id, instance_status[0]['AutoScalingGroupName']) return True return False def stop_idle_instances(region, tag_key, tag_values, idle_period_secs, minimum): ec2 = boto3.client('ec2', region_name=region) ec2res = boto3.resource('ec2', region_name=region) c = boto3.client('cloudwatch', region_name=region) values = tag_values.split(",") filters = [] if tag_key: f0 = {} f0['Name'] = "tag:{}".format(tag_key) f0['Values'] = values filters.append(f0) f1 = {} f1['Name'] = 'instance-state-name' f1['Values'] = ['running'] filters.append(f1) # print filters rs = ec2.describe_instances(Filters=filters) now = datetime.datetime.now(tzutc()) lookback = datetime.timedelta(seconds=idle_period_secs) time_start = now - lookback # print rs['Reservations'] for r in rs['Reservations']: for i in r['Instances']: launch_time = i['LaunchTime'] if is_in_autoscale_group(region, i['InstanceId']): continue age = now - launch_time if age < datetime.timedelta(seconds=idle_period_secs): print "Age of instance %s = %s, less than %s" %\ (i['InstanceId'], str(age), str(lookback)) continue dim = [{'Name': 'InstanceId', 'Value': i['InstanceId']}] period = idle_period_secs - (idle_period_secs % 60) if period < 60: period = 60 metric = c.get_metric_statistics(Period=period, StartTime=time_start, EndTime=now, MetricName='CPUUtilization', Namespace='AWS/EC2', Statistics=['Average'], Dimensions=dim) # print metric if metric['Datapoints']: average = metric['Datapoints'][0]['Average'] print "Average for %s is %f. Minimum is %f" \ % (i['InstanceId'], average, minimum) if average < minimum: print "About to stop instance %s" % i['InstanceId'] inst = ec2res.Instance(i['InstanceId']) inst.stop() if __name__ == "__main__": parser = argparse.ArgumentParser() -
chiradeep revised this gist
Dec 18, 2015 . 1 changed file with 14 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,9 +1,21 @@ import argparse import boto.ec2 import boto.ec2.cloudwatch import boto.ec2.autoscale import datetime def is_in_autoscale_group(region, instance_id): asg = boto.ec2.autoscale.connect_to_region(region) instance_status = \ asg.get_all_autoscaling_instances(instance_ids=[instance_id]) if instance_status: print "Instance %s is in autoscale group %s" \ % (instance_id, instance_status[0].group_name) return True return False def stop_idle_instances(region, tag_key, tag_values, idle_period_secs, minimum): ec2 = boto.ec2.connect_to_region(region) @@ -22,6 +34,8 @@ def stop_idle_instances(region, tag_key, tag_values, for i in r.instances: launch_time = datetime.datetime.strptime(i.launch_time, '%Y-%m-%dT%H:%M:%S.%fZ') if is_in_autoscale_group(region, i.id): continue age = now - launch_time if age < datetime.timedelta(seconds=idle_period_secs): print "Age of instance %s = %s, less than %s" %\ -
chiradeep revised this gist
Dec 18, 2015 . 1 changed file with 61 additions and 16 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,19 +1,64 @@ import argparse import boto.ec2 import boto.ec2.cloudwatch import datetime def stop_idle_instances(region, tag_key, tag_values, idle_period_secs, minimum): ec2 = boto.ec2.connect_to_region(region) c = boto.ec2.cloudwatch.connect_to_region(region) values = tag_values.split(",") filters = {} if tag_key: filters["tag:{}".format(tag_key)] = values filters['instance-state-name'] = 'running' # print filters reservations = ec2.get_all_reservations(filters=filters) now = datetime.datetime.utcnow() lookback = datetime.timedelta(seconds=idle_period_secs) time_start = now - lookback for r in reservations: for i in r.instances: launch_time = datetime.datetime.strptime(i.launch_time, '%Y-%m-%dT%H:%M:%S.%fZ') age = now - launch_time if age < datetime.timedelta(seconds=idle_period_secs): print "Age of instance %s = %s, less than %s" %\ (i.id, str(age), str(lookback)) continue metric = c.get_metric_statistics(60, time_start, now, 'CPUUtilization', 'AWS/EC2', 'Average', dimensions={'InstanceId': i.id}) if metric: # print metric[0] average = metric[0]['Average'] print "Average for %s is %f. Minimum is %f" \ % (i.id, average, minimum) if average < minimum: print "About to stop instance %s" % i.id # i.stop() if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--region", required=True, dest='region', default=None) parser.add_argument("--tag-key", required=False, dest='tag_key', default='instance-purpose') parser.add_argument("--tag-values", required=False, dest='tag_values', default='test') parser.add_argument("--idle-period-secs", required=False, dest='idle_period_secs', type=int, default=86400) parser.add_argument("--minimum-utilization", required=False, dest='minimum', type=float, default=0.05) result = parser.parse_args() stop_idle_instances(region=result.region, tag_key=result.tag_key, tag_values=result.tag_values, idle_period_secs=result.idle_period_secs, minimum=result.minimum) -
chiradeep created this gist
Dec 18, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,19 @@ import boto.ec2 import boto.ec2.cloudwatch ec2 = boto.ec2.connect_to_region('us-west-2') c = boto.ec2.cloudwatch.connect_to_region('us-west-2') instances = ec2.get_all_reservations(filters={'tag:instance-purpose':['test'], 'instance-state-name':'running'}) for i in instances: metric = c.get_metric_statistics( 60, datetime.datetime.utcnow() - datetime.timedelta(seconds=86400), datetime.datetime.utcnow(), 'CPUUtilization', 'AWS/EC2', 'Average', dimensions={'InstanceId':i.id}) average = metric[0]['Average'] if average < MINIMUM_UTILIZATION: i.stop()