Program to find get the summary of EMR clusters and EC2 instances running across all regions in an AWS account. This program can be executed via cron to get summary alerts in periodic intervals. An HTML email will be generated and send to the list of recipients mentioned in program. In this program, EMR and EC2 service summary are only considere…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
__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) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment