如何创建自动AWS计费报告

2020-10-18 15:07:05

Amazon提供创建计费警报的功能,可在您的AWS账单超过特定阈值时发出警报。但是,此方法有几个缺点:

您需要设置一个预定义的阈值。当您第一次开始使用AWS时,很难知道您的AWS账单会是什么样子。为了安全起见,很多人把这个门槛设得很低。

像这样的警报往往是被动的,而不是主动的。一旦超过阈值,就会触发警报。例如,我忘了关闭我不再使用的EC2实例,但大约一周后,当我的计费阈值超过限制时,我才发现这一点。

Cost Explorer确实提供了一个易于使用的界面,可以帮助您随时掌握账单数据。然而,这需要人们定期使用该工具,以确保我们不会遗漏任何东西。

在本文中,我们将研究如何构建一个简单的管道来通过电子邮件向我们发送账单报告。生成的报告将如下所示:

我们将创建一个名为app的新文件夹,该文件夹将存储Cost Explorer API和使用SES的应用程序逻辑。

我们还将在根目录中创建一个名为handler.py的文件。该文件将包含用于生成计费报告的逻辑。

我们将使用Cost Explorer中的Cost and Usage端点来获取所需的计费数据。

从datetime导入boto3从dateutil.relativedelta导入relativedelta类CostExplorer:TODAY_DATE=DATETIME。Utcnow()。Date()cur_Month_Date=TODAY_DATE。替换(DAY=1)PRIV_MONTER_DATE:DATE=CUR_MONTER_DATE-Relativedelta(MONTS=+1)def__init__(Self):self。客户端=boto3。客户(";ce";)本人。指标=[";UNBLANDED_COST";]自身。币种:str=";美元;本身。Daily_report_kwargs={";时间段";:自我。_Get_Time Period(START=SELF。TODAY_DATE-TIMEDAR(DAYS=2),#START_DT包含END=SELF。TODAY_DATE,#END_DT是独占的),";指标";:SELF。指标,";粒度";:";每日";}自身。Monthly_Report_kwargs={";时间段";:自我。_Get_Time Period(START=SELF。PRIV_MONTH_DATE,#START_DT包含END=SELF。TODAY_DATE,#END_DT是独占的),";指标";:SELF。指标,";粒度";:";每月";}def_get_timePeriod(self,start:date,end:date):return{";start";:start。Isoformat(),";End";:End。Isoformat(),}def_get_data(self,result):";";";";从成本资源管理器数据中检索单个帐单行。结果:行={";日期";:v[";时间段";][";开始";]}v[";Groups";]:Key=i[";Keys";][0]行中i的";";";";";";行=[]。更新({key:Float(I[";Metrics&34;][";UnblendedCost";][";Amount";])})行。更新({";Total";:Float(v[";Total";][";UnblendedCost";][";Amount";])})行。Append(Row)return[f";{row[';date';]}:{round(row[';Total';],2)}";针对行中的行]def GENERATE_REPORT(SELF,REPORT_KWARGS):";";";根据粒度、开始日期和结束日期获取成本数据。";";";响应=自我。客户。GET_COST_AND_USAGE(**REPORT_KWARGS)返回";\n";。加入(自我)。_GET_DATA(Response[";ResultsByTime";])。

我们希望生成两个报告,一个是最近2天的报告(每日粒度),另一个是比较上个月与当前月的支出(每月粒度)。

我们使用未混合成本来表示我们的账单数据。有关这方面的更多信息可以在此处找到。

SES需要经过验证的电子邮件地址才能使用。可以通过AWS控制台进行验证。

导入boto3 class EmailClient:Sender=";Sendder=";AWS Cost Alert<;[电子邮件受保护]>;";Subject=";每日AWS账单报告";#具有非HTML电子邮件客户端的收件人的电子邮件正文。Body_Text=";";";";AWS计费警报\r\n每日计费报告\r\n{DAILY_BILLING_REPORT}\r\n{MONTRATE_BILLING_REPORT}\r\n";";";#电子邮件的HTML正文。Body_html=";&34;<;html>;<;head>;<;/head>;<;body>;<;h1>;AWS计费预警<;/h1>;<;hr/>;h3>;每日账单<;/h3>;<;p>;{Daily_billing_report}<;/p>;<;hr/>;<;H3>;每月账单<;/h3>;<;p>;{Monthly_Billing_Report}<;/p>;<;/body>;<;/html>;";";";#电子邮件的字符编码。Charset=";UTF-8";#收件人电子邮件地址Recipient=";[电子邮件受保护]";def__init__(Self):自我。客户端=boto3。客户端(";SES";)def send(SELF,DAILY_BILLING_REPORT,MONTAY_BILLING_REPORT):";";";";发送包含AWS计费数据的电子邮件";";";电子邮件_TEXT=SELF。正文(_Text)。格式(Daily_Billing_Report=Daily_Billing_Report,Monthly_Billing_Report=Monthly_Billing_Report)email_html=self。Body_HTML。格式(DAILY_BILLING_REPORT=DAILY_BILLING_REPORT,MOUNTAL_BILLING_REPORT=MONTRATE_BILLING_。客户。发送电子邮件(Destination={";ToAddresses";:[Self.。收件人,],},邮件={";正文";:{";HTML";:{";字符集";:自我。字符集,";data";:email_html},";text";:{";Charset";:Self。字符集,";数据";:电子邮件_文本,},},";主题";:{";字符集";:自我。字符集,";数据";:自我。主题,},},来源=自我。发件人,)。

现在,我们将使用成本资源管理器和SES生成报告。用下面的代码片段替换handler.py的内容:

从app.ost_explorer导入CostExplorer从app.email导入EmailClient def main():ce=CostExplorer()Daily_report=ce。生成报告(CE.。Daily_report_kwargs)Monthly_Report=ce。生成报告(CE.。Monthly_Report_kwargs)Email_Client=EmailClient()Email_Client。发送(DAILY_BILLING_REPORT=DAILY_REPORT,MOUNTAL_

既然我们已经在本地生成了账单报告,我们将利用无服务器框架使用AWS Lambda创建无服务器管道。

Serverless-python-requirements插件自动捆绑Requirements.txt中的依赖项,并使它们可用于Lambda函数。

服务:无服务器成本警报插件:-serverless-python-Requirements Package:excludeDevDependency:true exclude:-node_module/**custom:pythonRequirements:slm:true strie:false slimPatternsAppendDefaults:true slimPatterns:-";**/*.Egg-info*";-";**/*.dist-info*";DockerizePip:true Provider:Name:AWS运行时:python3.7阶段:dev Region:us-west-2 iamRoleStatements:-Effect:Allow Action:-ses:SendEmail Resource:-";*";-Effect:Allow Action:-ce:GetCostAndUsage Resource:-";*";Functions:Send_Daily_Cost_Report:Handler.Generate_Report Events:-http:Get hello。

Lambda函数将有权查询成本资源管理器中的CostAndUsage函数和SES中的SendEmail。

在将Lambda函数部署到AWS之前,我们需要更新Lambda函数,以便它可以响应HTTP请求。使用以下代码片段更新handler.py的内容:

从app.ost_explorer导入CostExplorer从app.email导入EmailClient def GENERATE_REPORT(event,context):ce=CostExplorer()Daily_report=ce。生成报告(CE.。Daily_report_kwargs)Monthly_Report=ce。生成报告(CE.。Monthly_Report_kwargs)Email_Client=EmailClient()Email_Client。发送(Daily_Billing_Report=Daily_Report,Monthly_Billing_Report=Monthly_Report)return{";statusCode";:200,";Header";:{";Content-Type";:";Application/json";,},";Body";:";Success";,}。

现在,我们将Lambda功能部署到AWS。在您的终端中运行以下命令:

如果部署成功,您应该能够看到Lambda的HTTP端点,如下所示:

最后,我们将更新Lambda函数,使其作为预定的cron而不是HTTP端点运行。我们将把Lambda函数设置为每天运行一次。

功能:SEND_DAILY_COST_REPORT:#HANDLER:handler.Generate_Report#events:#-http:GET hello HANDLER:HANDLER。GENERATE_REPORT事件:-Schedule:Cron(0 9**?*)。

在过去的几周里,我一直在使用这个设置,它对保持我的AWS账单非常有用,而不必担心频繁检查控制台。Cost Explorer API有很多不同的报告选项,您可以生成适合您的报告。