作者:光环云 刘立冬
AWS Lambda介绍
AWS Lambda 让您无需预置或管理服务器即可运行代码。您只需按消耗的计算时间付费 – 代码未运行时不产生费用。借助 Lambda,您几乎可以为任何类型的应用程序或后端服务运行代码,而且全部都无需管理。只需上传您的代码,Lambda 就会处理运行和扩展高可用性代码所需的一切工作。您可以将您的代码设置为自动从其他 AWS 产品触发,或者直接从任何 Web 或移动应用程序调用。
本文要介绍就是使用Lambda实现每天定时发送所有区域正在运行EC2实例的信息
笔者账号中的实例信息
1 创建一个有权限访问ec2和执行lambda的角色
2 创建Lambda函数
2.1 创建Lambda函数
运行环境:Python 2.7
角色:上面创建的角色
最大内存:128M
超时:1分钟
单击"创建函数"在代码区域粘贴以下代码:
import os
from email.mime.text import MIMEText
from email.header import Header
def lambda_handler(event,context):
import boto3
import datetime
ports=set()
public_cidr={'CidrIp':'0.0.0.0/0'}
html_body_inner=""
count=0
# initialize variables
username = os.environ['USERNAME']
password = os.environ['PASSWORD']
host = os.environ['SMTPHOST']
port = os.environ['SMTPPORT']
mail_from = os.environ.get('MAIL_FROM')
mail_to = os.environ['MAIL_TO'] # separate multiple recipient by comma. eg: "abc@gmail.com, xyz@gmail.com"
#origin = os.environ.get('ORIGIN')
#origin_req = event['headers'].get('Host')
subject = "ec2 status"
body = ""
reply_to =""
#reply_to = event['queryStringParameters'].get('reply')
#subject = event['queryStringParameters']['subject']
#body = event['body']
response=boto3.client("ec2").describe_regions()
# Iterating over all regions
for regname in response['Regions']:
ec2=boto3.client("ec2",region_name=regname['RegionName'])
all_instances=ec2.describe_instances(Filters=[{'Name':'instance-state-name','Values':['running']}])
for res in all_instances["Reservations"]:
for instance in res["Instances"]:
count=count+1
ports=set()
size=instance["InstanceType"][instance["InstanceType"].find(".")+1:]
# Checking if the running instance has open ports and fetching the list of open ports
for SG in instance["SecurityGroups"]:
desc_sg=ec2.describe_security_groups(GroupIds=[ SG["GroupId"]])
for sec_grp in desc_sg["SecurityGroups"]:
for ip_per in sec_grp["IpPermissions"]:
for cidr in ip_per["IpRanges"]:
if cidr == public_cidr:
if ip_per.get("FromPort"):
ports.add(ip_per["FromPort"])
else:
ports.add('ALL')
# Print instance details if it has open ports
if len(ports)==0 :
ports.add('----')
ports = ",".join(repr(e) for e in ports).replace("'","")
instance_name="----"
if instance. get("Tags"):
for tag in instance["Tags"]:
if tag["Key"]=="Name":
instance_name=tag["Value"]
html_body_inner = html_body_inner + ("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td bgcolor=white>%s</td><td>%s</td><td bgcolor=white>%s</td></tr>"%(count,regname['RegionName'],instance["InstanceId"],instance_name,instance["InstanceType"],ports,instance["LaunchTime"].date()))
# Create HTML Report
html_body ="<! DOCTYPE html><html><body>"
html_body = html_body + ("<h3>Total number of running instances: %s</h3>" %(count))
html_body = html_body + '<table border="1" CELLPADDING=1 CELLSPACING=0 width="86%"><col width="2%"><col width="13%"><col width="17%"><colwidth="14%"><col width="5%"><col width="15%"><col width="10%"><col width="10%"><tr bgcolor="#5BAAF5"><th><font color="# fff">Sr.</font></th><th><font color="# fff">Region</font></th><th><font color="# fff">Instance Id</font></th><th><font color="# fff">Instance Name</font></th><th><font color="# fff">Type</font></th><th><font color="# fff">Publicly Open Ports</font></th><th><font color="# fff">Launch Date</font></th></tr>'
html_body = html_body + html_body_inner + '</table></body></html>'
# Send email notification ses=boto3.client('ses')
#body = html_body
#body = MIMEText(body, 'HTML','utf-8')
#body = MIMEText(body,_subtype='html',_charset='gb2312')
#body.replace_header('content-transfer-encoding', 'quoted-printable')
#subject = Header(subject, 'utf-8')
body = MIMEText(html_body, 'html', 'utf-8')
body = body.as_string()
success = send_email(host, port, username, password, subject, body, mail_to, mail_from, reply_to)
def send_email(host, port, username, password, subject, body, mail_to, mail_from = None, reply_to = None):
if mail_from is None: mail_from = username
if reply_to is None: reply_to = mail_to
#message = """From: %s\nTo: %s\nReply-To: %s\nSubject: %s\n\n%s""" % (mail_from, mail_to, reply_to, subject, body)
#print (message)
try:
server = smtplib.SMTP(host, port)
server.ehlo()
server.starttls()
server.login(username, password)
server.sendmail(mail_from, mail_to, body)
server.close()
return True
except Exception as ex:
print (ex)
return False
2.2 发件人用户名密码,smtp地址、端口,收件人地址通过环境变量传入
MAIL_FROM
MAIL_TO
PASSWORD
SMTPHOST
SMTPPORT
USERNAME
3 创建cloud watch event
Cron表达式 格式为 分 、时、日、月、周、年
Timezone 为 UTC
如图设定为每天早上10:27发送(北京时间)Lambda实现每天定时发送所有区域正在运行EC2实例的信息