Amazon webservices is one among the popular cloud service providers. I am using almost all services provided by AWS. While using the cloud services, we have to be careful about the cost. We should stop or terminate all the unused services, otherwise it may result in huge money loss. This is a small python utility for getting the summary of EC2 instances and EMR clusters across all regions in an aws account. I scheduled this utility as a cron job for getting periodic emails. Similar to this code, you can create the summary utility for all the other services in AWS. This code is working fine at the time of development. The API changes may happen, you have to make the changes in the code accordingly.

__author__ = 'Amal G Jose'
import sys
import smtplib
import time
import boto
import boto.ses
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from ConfigParser import SafeConfigParser
from boto.regioninfo import RegionInfo
from boto.emr.connection import EmrConnection
BASE_HTML = """<!DOCTYPE html>
<html>
<head>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
text-align: left;
}
</style>
</head>
<body>
"""
END_HTML = """
</body>
</html>
"""
EMR_HEADER = """
<table style="width:100%">
<caption><b>EMR Cluster Details</b></caption>
<tr>
<th>Cluster Name</th>
<th>Number of Nodes</th>
<th>Instance Type</th>
<th>Cluster Creation Date</th>
<th>Region</th>
</tr>
"""
EC2_HEADER = """
<table style="width:100%">
<caption><b>EC2 Instance Details</b></caption>
<tr>
<th>EC2 Name</th>
<th>Instance Id</th>
<th>Instance Type</th>
<th>Region</th>
</tr>
"""
TABLE_END = """</table>"""
LINE_BREAK = "<br> <br> <br>"
class GetSummary(object):
##Initializer
def __init__(self):
self.from_email_id = "sender@email.com"
self.email_password = "xxxxxxxxxxxx"
self.aws_access_key = 'XXXXXXXXXXXXXXXXXX'
self.aws_secret_key = 'XXXXXXXXXXXXXXXXXX'
to_address = "receiver1@email.com,receiver2@email.com,receiver3@email.com"
self.receiver_email = to_address.split(',')
##Method for getting the details of EMR
def get_all_emr(self, regions):
try:
html_data = EMR_HEADER
for region in regions:
emr_conn = EmrConnection(self.aws_access_key, self.aws_secret_key,
region=RegionInfo(name=region,
endpoint=region + '.elasticmapreduce.amazonaws.com'))
cluster_list = emr_conn.describe_jobflows()
for cluster in cluster_list:
if cluster.state in ['RUNNING', 'WAITING', 'STARTING', 'BOOTSTRAPPING']:
try:
row_html = """<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
</tr>""" % (cluster.name, str(cluster.instancecount), cluster.masterinstancetype, cluster.creationdatetime, region)
html_data += row_html + "\n"
except:
pass
return html_data + TABLE_END
except Exception, e:
print "Exception occurred while getting the details of EMR cluster : " + str(e)
##Method for getting the details of EC2
def get_all_running_instances(self, regions):
try:
emr_groups = ['ElasticMapReduce-slave', 'ElasticMapReduce-master']
html_data = EC2_HEADER
for region in regions:
conn = boto.ec2.connect_to_region(region,
aws_access_key_id=self.aws_access_key,
aws_secret_access_key=self.aws_secret_key)
##List all running EC2 instances
reservations = conn.get_all_reservations()
for reservation in reservations:
for instance in reservation.instances:
if instance.state in ['running'] and (instance.groups[0].name not in emr_groups):
try:
row_html = """<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
</tr>""" % (instance.tags['Name'], instance.id, instance.instance_type,region )
except:
row_html = """<tr>
<td>Unknown</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
</tr>""" % (instance.id, instance.instance_type, region)
html_data += row_html + '\n'
return html_data + TABLE_END
except Exception, e:
print "Error occurred while getting EC2 instance details : " + str(e)
##Method to send email alerts
def send_email(self, email_body):
SUBJECT = "AWS Account Summary"
try:
localtime = time.asctime( time.localtime(time.time()))
recepients = ','.join(self.receiver_email)
msg = MIMEMultipart('alternative')
msg['Subject'] = SUBJECT + " " + str(localtime)
msg['From'] = self.from_email_id
msg['To'] = recepients
msg_part = MIMEText(email_body, 'html')
msg.attach(msg_part)
server = smtplib.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.login(self.from_email_id, self.email_password)
server.sendmail(self.from_email_id, self.receiver_email, msg.as_string())
server.close()
print 'Email Sent Successfully'
except Exception, e:
print "Failed to send email : " + str(e)
if __name__== '__main__':
get_summary = GetSummary()
regions = ['ap-southeast-1', 'ap-southeast-2', 'ap-northeast-1',
'us-east-1','us-west-1', 'us-west-2','eu-west-1', 'sa-east-1']
ec2_details = get_summary.get_all_running_instances(regions)
emr_details = get_summary.get_all_emr(regions)
complete_details = BASE_HTML + emr_details + LINE_BREAK + ec2_details + END_HTML
get_summary.send_email(complete_details)

view raw
GetAWSSummary.py
hosted with ❤ by GitHub