Reputation: 658
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'
Upvotes: 2
Views: 2897
Reputation: 658
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))
Upvotes: 0