Aws
20 Jun 2018

How to delete Spot Instances using a Lambda function

Note: The sample code below was written for Python 2. For current Lambda runtimes (Python 3.x), use print() as a function and ensure the handler signature and boto3 usage match the Lambda Python documentation.

I know, almost everybody knows how to delete instances using lambda functions, but, there is a small difference between a regular EC2 instance and spot instances. In this case, let’s say that the spot instances are slaves or workers for the EC2 instances.

You would need to use some additional libraries if you want this script works, those libraries are not installed by default on AWS, that’s why you need to build this script locally (on your PC) before pushing it to AWS.

Those libraries are pytz and datetime.

I just added a small script that will install those libraries and compress the whole code before push it to AWS.

#!/usr/bin/env bash

pip install -t . pytz
pip install -t . datetime
pip install -t . logging
zip -r lambda.zip .

As you can see we look for all the spot instances that have been fulfilled (created and running); otherwise it will fail with cancelled or terminated instances. We terminate those spot instances that have been running for more than 10h one by one.

import boto3
import logging
from datetime import datetime
from datetime import timedelta
from pytz import timezone
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)




def lambda_handler(event, context):
    client = boto3.client('ec2')
    instances = client.describe_spot_instance_requests(Filters=[{'Name': 'status-code','Values': ['fulfilled']}] )
    est = timezone('<AZ timezone>')
    print est.localize(datetime.now())
    instance=[]
    for r in instances['SpotInstanceRequests']:
        print r['InstanceId']
        print r['Status']['UpdateTime']
        if r["CreateTime"] < est.localize(datetime.now() - timedelta(hours=10)):
            print "Instance Terminated Due more than 10h from creation time"
            instance.append(r['InstanceId'])
            client.terminate_instances( DryRun=False, InstanceIds=instance )
        else:
            print "Instance OK"
    return 1



Tags: