Skip to content

Instantly share code, notes, and snippets.

@z-shah
Created May 15, 2017 23:43
Show Gist options
  • Save z-shah/aa74a46231c1135f7378b70c4768eb99 to your computer and use it in GitHub Desktop.
Save z-shah/aa74a46231c1135f7378b70c4768eb99 to your computer and use it in GitHub Desktop.
import boto3
import json
import time
config = {
'tag': 'schedule',
'exclude': ['i-071a35b4439f1a581'],
'exclude-tag': '',
'default': '{"mon": {"start": 7, "stop": 19},"tue": {"start": 7, "stop": 19},"wed": {"start": 7, "stop": 19},"thu": {"start": 7, "stop": 19},"fri": {"start": 7, "stop": 19},"sat": {"start": 7, "stop": 19},"sun": {"start": 15, "stop": 16}}'
}
sps = ['Launch', 'Terminate', 'HealthCheck', 'ReplaceUnhealthy', 'AZRebalance']
#
# Loop EC2 instances and check if a 'schedule' tag has been set. If not, create it using default schedule. Next, evaluate value and start/stop instance if needed.
#
def lambda_handler(event, context):
print "=== Start parsing AWS schedule."
ec2 = boto3.client('ec2')
asc = boto3.client('autoscaling')
response = ec2.describe_instances()
# Get current day + hour (using GMT)
hh = int(time.strftime("%H", time.localtime()))
day = time.strftime("%a", time.localtime()).lower()
# Print full date and time to log for records
from time import gmtime, strftime
fulldatetime = strftime("%a, %d %b %Y %H:%M:%S", gmtime())
print "=== This schedule run is beginning at %s UTC time" % fulldatetime
started = []
stopped = []
exclude_list = config['exclude']
# Loop reservations/instances.
for r in response['Reservations']:
for ins in r['Instances']:
if (ins['InstanceId'] not in exclude_list) and (not any('ignore' in t['Key'] for t in ins['Tags'])):
try:
data = None
for tag in ins['Tags']:
if tag['Key'] == 'schedule':
data = tag['Value']
if tag['Key'] == 'aws:autoscaling:groupName':
asg = tag['Value']
if data is None:
create_schedule_tag(ins, ec2)
data = config['default']
schedule = json.loads(data)
try:
if hh == schedule[day]['start'] and not ins['State']['Name'] == 'running':
print "Starting instance %s" % ins['InstanceId']
started.append(ins['InstanceId'])
ec2.start_instances(InstanceIds=[ins['InstanceId']])
except:
pass # catch exception if 'start' is not in schedule.
try:
if hh == schedule[day]['stop'] and ins['State']['Name'] == 'running':
if asg is not None:
print "Suspending autoscaling process for ASG %s before shutting down the instance." % asg
asc.suspend_processes(AutoScalingGroupName=asg, ScalingProcesses=sps)
print "Stopping instance %s" % ins['InstanceId']
stopped.append(ins['InstanceId'])
ec2.stop_instances(InstanceIds=[ins['InstanceId']])
except:
pass # catch exception if 'stop' is not in schedule.
asg = None
except KeyError as e:
create_schedule_tag(ins, ec2)
except ValueError as e:
# invalid json
print 'Invalid value for tag "schedule" on instance "%s", please check!' % (ins['InstanceId'])
else:
print "Instance %s is successfully ignored." % ins['InstanceId']
# Fix ELB configuration - not working currently
'''
# TODO: Deregister and register from ELB only if instances are not InService.
if len(started) > 0:
print "Instances have been started... Checking instances in Elastic Load Balancer."
elb = boto3.client('elb')
lbd = elb.describe_load_balancers()
for e in lbd['LoadBalancerDescriptions']:
for inss in e['Instances']:
if inss['InstanceId'] in started:
print "Deregistering instance %s from ELB %s" % (inss['InstanceId'], e['LoadBalancerName'])
elb.deregister_instances_from_load_balancer(LoadBalancerName=e['LoadBalancerName'],
Instances=[{'InstanceId': inss['InstanceId']}])
time.sleep(3)
print "Registering instance %s with ELB %s" % (inss['InstanceId'], e['LoadBalancerName'])
elb.register_instances_with_load_balancer(LoadBalancerName=e['LoadBalancerName'],
Instances=[{'InstanceId': inss['InstanceId']}])
'''
print "=== Finished parsing AWS schedule."
def create_schedule_tag(instance, ec2):
if instance['InstanceId'] not in config['exclude']:
try:
tag_name = config['tag']
tag_value = config['default']
print "About to create tag on instance %s with value: %s" % (instance['InstanceId'], tag_value)
ec2.create_tags(Resources=[instance['InstanceId']], Tags=[{'Key': tag_name, 'Value': tag_value}])
except Exception as e:
print e
else:
print "Instance %s is successfully ignored." % instance.id
if __name__ == '__main__':
lambda_handler('event', 'handler')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment