AWS Lambda to terminate instances

Since you are here I’m assuming that you already know that Amazon lambda is a server-less managed compute service which basically runs function triggered by configurable events. This post covers the steps to configure lambda to terminate an EC2 instance based on S3 bucket event trigger.

 

 

Lets consider a scenario –  You create an ec2 instance provision it with your application environment, build your application, trigger the application to process the data, capture results & then this instance needs to be terminated. This can be done using lambda function without even parent process needing to wait until application process finishes.

A lambda function needs to be configured with of course, EC2 access, S3 bucket read & cloudwatch access to log the events.

  1. Create an IAM policy -Use this IAM policy json file to create a new policy on AWS console IAM policy page.
  2. Create an IAM role for Lambda –  Create a new role for AWS Lambda service & attach the policy created in the step 1.
  3. Create a lambda function –  Let see how to create a new lambda function with python3
    • Go to Lambda service on AWS console page & click on create function button.
    • Select author from scratch -> Specify desired function name -> Runtime python 3.6 -> choose existing role (the one we created in step2 above)
    • Click create function & on the next page select trigger as S3
    • In configure trigger section select the relevant bucket name where your lambda function will look for success file with instance id.
    • Select event type as Object created
    • select prefix as your desired filename; Note that your lambda function will look for this file prefix in the above mentioned bucket. Lets set this prefix as success
    • Now from the designer pane click on the lambda function name, this should open a code editor at the bottom of the screen, paste the lambda function from the below snippet in the editor & click save.
import logging
import boto3

logger = logging.getLogger()
logger.setLevel(logging.INFO)
region = ‘eu-west-2’

s3 = boto3.client(‘s3’)
ec2 = boto3.client(‘ec2’, region_name=region)

def lambda_handler(event, context):
    logger.info(‘Event Details-{}’.format(event))
    bucket_name = event[‘Records’][0][‘s3’][‘bucket’][‘name’]
    file_key = event[‘Records’][0][‘s3’][‘object’][‘key’]
    logger.info(‘Reading {} from {}’.format(file_key, bucket_name))
    obj = s3.get_object(Bucket=bucket_name, Key=file_key)
    lines_from_success_file = obj[‘Body’].read().split(b’\n’)
    instance_ids=[]
    for instance_id in lines_from_success_file:
        if instance_id:
            instance_ids.append(instance_id)
    logger.info(‘Instance to terminate -{}’.format(instance_ids))
    ec2.terminate_instances(InstanceIds=instance_ids)

And that’s it, now if you create a text file as success.txt in the configured bucket with instance id of any running instance in it; you will be able to see lambda in action. Lambda function will get triggered as soon as you upload file & you can see logs in the cloudwatch with series of events & the instance will be terminated.

Leave a Reply

Your email address will not be published. Required fields are marked *

    {
        “Version”: “2012-10-17”,
        “Statement”: [
            {
                “Effect”: “Allow”,
                “Action”: “logs:CreateLogGroup”,
                “Resource”: “arn:aws:logs:eu-west-2:<aws_account_number>:*”
            },
            {
                “Effect”: “Allow”,
                “Action”: [
                “logs:CreateLogStream”,
                “logs:PutLogEvents”
                ],
                “Resource”: [“arn:aws:logs:eu-west-2::log-group:/aws/lambda/<lambda_function_name>:*”]
            },
            {
                “Effect”: “Allow”,
                “Action”: [“s3:ListBucket”],
                “Resource”: [“arn:aws:s3:::”]
            },
            {
                “Effect”: “Allow”,
                “Action”: [
                    “s3:Get*”,
                    “s3:List*”,
                    “s3:PutObject*”,
                    “s3:DeleteObject*”
                ],
                “Resource”: [“arn:aws:s3:::/*”]
            },
            {
                “Effect”: “Allow”,
                “Action”: [
                    “ec2:Start*”,
                    “ec2:Stop*”,
                    “ec2:Terminate*”
                ],
                “Resource”: “*”
            }
        ]
}