2
votes

For each AWS region

1.Get all EC2 instances that either

2.are Tagged with tag Owner and value Unknown or unknown

3.are missing tag Owner

For each EC2 instance

4.Check if the instance has a tag "Terminate_On"

Else

5.Tag the instance with a tag "Terminate_On" and value of the date 7 days from now.

steps 1,2 and 3 are completed:

import boto3   
import collections     
import datetime     
import time     
import sys 
from datetime import datetime
from dateutil.relativedelta import relativedelta

ec = boto3.client('ec2', 'eu-west-1')     
ec2 = boto3.resource('ec2', 'eu-west-1')     
date_after_month = datetime.now()+ relativedelta(days=7)
#print date_after_month.strftime('%d/%m/%Y')  

def lambda_handler(event, context):  

    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 not 'Owner' in tags:
                a =  instance['InstanceId'] + " does not have Owner tag"
            elif tags['Owner'] in ['Unknown', 'unknown']:
                b = instance['InstanceId'] + " has [U|u]nknown Owner tag"
            if not 'TerminateOn' in tags:  
                ec2.create_tags(
                    Resources=[instance['InstanceId']],
                    Tags= [{
                        'Key':'TerminateOn', 
                        'Value':date_after_month.strftime('%d/%m/%Y')}])  
            #print a+" "+b

4.for instances returned from above code (Instances with Owner tags and instances without owner tag) check if Terminate_On tag exists

5.if not, create that tag with date_after_month.strftime('%d/%m/%Y') as value

The issues is on step 5, if one EC2 instance is running, no problem, tag is created, but if more than one, then tag is created only for first one

and following error is shown:

for tag in instance['Tags']:
KeyError: 'Tags'
1
Add some print statements or logging to see what is in instance variableFelixEnescu

1 Answers

0
votes

Complete solution:

import boto3   
import collections     
import datetime     
import time     
import sys 

ses = boto3.client('ses')

email_from = 'Email'
email_to = 'Email'
email_cc = 'Email'
emaiL_subject = 'Subject'
email_body = 'Body'






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 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 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)
                     print "terminated" + str(instance_ids)
                     #send email that instance is terminated

                    else: 
                    #Send an email to engineering that this instance will be removed X amount of days (calculate the date based on today's date and the termination date."

                      now=datetime.now()
                      future=tags["TerminateOn"]
                      TerminateOn = datetime.strptime(future, "%d/%m/%Y")
                      days= (TerminateOn-now).days
                      print str(instance_ids) +  " will be removed in "+ str(days) + " days"


              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)

                  print "was shut down "+format(','.join(instance_ids))