Python Lambda script for Cleaning Up unused Amazon EC2 instances

Posted: June 15, 2018 in Amazon Web Services (AWS), Scripts

This script performs following:

Untitled.png

import boto3
import collections
import datetime
import time
import sys 
ses = boto3.client('ses')
AWSAccountID=boto3.client('sts').get_caller_identity()['Account']
AWSUser=boto3.client('sts').get_caller_identity()['UserId']
ec = boto3.client('ec2', 'eu-west-1')
ec2 = boto3.resource('ec2', 'eu-west-1')
from datetime import datetime
from dateutil.relativedelta import relativedelta

#create date variables 

date_after_month = datetime.now()+ relativedelta(days=7)
#date_after_month.strftime('%d/%m/%Y')
today=datetime.now().strftime('%d/%m/%Y')

def send_mail(email_from, email_to, subject, body):
    smtp_address = 'smtp.office365.com'
    provider_username = 'sender@company.com'
    provider_password = 'Pass'
    smtpserver = smtplib.SMTP(smtp_address, 587)
    smtpserver.ehlo()
    smtpserver.starttls()
    smtpserver.ehlo() # extra characters to permit edit
    smtpserver.login(provider_username, provider_password)
    header = 'To: ' + email_to + '\n' + 'From: ' + email_from + '\n' + 'Subject: ' + subject + '\n'
    msg = header + '\n ' + body + ' \n\n'
    smtpserver.sendmail(provider_username, email_to, msg)
    smtpserver.quit()
def lambda_handler(event, context):
  #Get instances with Owner Taggs and values Unknown/known
    instance_ids = []
    reservations = ec.describe_instances().get('Reservations', []) 

    for reservation in reservations:
     for instance in reservation['Instances']:
        tags = {}
        for tag in instance['Tags']:
            tags[tag['Key']] = tag['Value']
            if tag['Key'] == 'Name':
              name=tag['Value']
        if not 'Owner' in tags or tags['Owner']=='unknown' or tags['Owner']=='Unknown':
              instance_ids.append(instance['InstanceId'])  

                #Check if "TerminateOn" tag exists:

              if 'TerminateOn' in tags:
                  #compare TerminteOn value with current date
                    if tags["TerminateOn"]==today:

                    #Check if termination protection is enabled
                     terminate_protection=ec.describe_instance_attribute(InstanceId =instance['InstanceId'] ,Attribute = 'disableApiTermination')
                     protection_value=(terminate_protection['DisableApiTermination']['Value'])
                     #if enabled disable it
                     if protection_value == True:
                        ec.modify_instance_attribute(InstanceId=instance['InstanceId'],Attribute="disableApiTermination",Value= "False" )
                    #terminate instance
                     ec.terminate_instances(InstanceIds=instance_ids)
                     body="AWS Account:" + AWSUser + "\n\nAWS Account Number:" + AWSAccountID + "\n\nInstance Name:" + name + "\n\nInstance ID:" + instance['InstanceId'] + "\n\nTo be Removed In:Now\n\n\n\rNote:\n\nOwner tag is missing from this instance, hence,instance is removed." 
                     send email that instance is terminated
                     send_mail('sender@example.com', 'recipient@example.com', 'Ireland:Notification of terminating instances', body)

                    else:
                      

                      now=datetime.now()
                      future=tags["TerminateOn"]
                      TerminateOn = datetime.strptime(future, "%d/%m/%Y")
                      days= (TerminateOn-now).days
                      body="AWS Account:" + AWSUser + "\n\nAWS Account Number:" + AWSAccountID + "\n\nInstance Name:" + name + "\n\nInstance ID:" + instance['InstanceId'] + "\n\nTo be Removed In:" + str(days) + "days\n\n\n\rNote:\n\nOwner tag is missing from this instance, hence,instance is removed."
                      send_mail('sender@example.com', 'recipient@example.com', 'Ireland:Notification of terminating instances', body)
                      ec.stop_instances(InstanceIds=instance_ids)

              else:
                 if not 'TerminateOn' in tags:#, create it
                  ec2.create_tags(Resources=instance_ids,Tags=[{'Key':'TerminateOn','Value':date_after_month.strftime('%d/%m/%Y')}])
                  ec.stop_instances(InstanceIds=instance_ids)
                  body="AWS Account:" + AWSUser + "\n\nAWS Account Number:" + AWSAccountID + "\n\nInstance Name:" + name + "\n\nInstance ID:" + instance['InstanceId'] + "\n\nTo be Removed In:Six Days from now\n\n\n\rNote:\n\nOwner tag is missing from this instance.\nIf you do not wish this instance to be removed, please update the Owner tag." 
                  send_mail('sender@example.com', 'recipient@example.com', 'Ireland:Notification of shutting down instances', body)
                  

Advertisements
Comments
  1. Anonymous says:

    Is this for python 2.7 or 3.6 in lambda? Either or both return multiple errors to troubleshoot.

    Like

  2. Anonymous says:

    Update – this was the issue:
    today=datetime.now().strftime(‘%d/%m/%Ydef lambda_handler(event, context):
    Should be
    today=datetime.now().strftime(‘%d/%m/%Y’)
    def lambda_handler(event, context):

    And it seems to work in Python 2.7

    Like

  3. Anonymous says:

    Actually one more error I found after triggering it with a cron schedule in Lambda:

    ‘Tags’: KeyError
    Traceback (most recent call last):
    File “/var/task/lambda_function.py”, line **, in lambda_handler
    for tag in instance[‘Tags’]:
    KeyError: ‘Tags’

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s