AWSの昨日までの各サービスの利用料金をSlackに通知させる

AWSで、昨日までの各サービス、アカウント全体での利用料金についてSlackでポストさせるようにしたかったので、とりあえずPythonで簡単なスクリプトを作ってみた。
Lambdaでやってもよかったのだが、手元にあるジョブサーバを使わないといかんという使命感の元普通にサーバ上で動くようにした。認証情報についても事前にexportしとけばいけるはずなのだが、とりあえずスクリプト内で記述するようにしてる。
利用料金についてCloudWatchに連携されている必要があるので、事前にCloudWatchへの連携をしておくこと。
ライブラリとしてboto3とSlackWebを使っている。

●AWSBillingInfoPost.py

python
#!/usr/bin/env python # -*- coding: utf-8 -*- import os,sys,json,datetime import boto3 import slackweb # ==== AWS認証情報 ==== AWS_REGION = "us-east-1" AWS_KEY_ID = "アクセスキー" AWS_SECRET_KEY = "シークレットキー" # ==== AWS認証処理 ==== aws_session = boto3.Session( aws_access_key_id=AWS_KEY_ID, aws_secret_access_key=AWS_SECRET_KEY, region_name=AWS_REGION ) cloudwatch_conn = aws_session.client('cloudwatch') # ==== Slack認証設定 ==== SLACK_WEBHOOK='https://hooks.slack.com/services/XXXXXXXX/XXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXX' SLACK_CHANNEL='#チャンネル名' SLACK_USER='Postユーザ' # ==== 昨日の日付を取得する ==== last_date = (datetime.date.today() -datetime.timedelta(1)).strftime('%Y/%m/%d') # ==== 関数get_value() ==== # ※ get_value(サービス名)で昨日までのサービス利用料金を取得する # サービス名が「ALL」の場合は全体の金額を取得する def get_value(service_name): if service_name == 'ALL': get_demesion = [{'Name': 'Currency', 'Value': 'USD'}] else: get_demesion = [{'Name': 'ServiceName', 'Value': service },{'Name': 'Currency', 'Value': 'USD'}] data = cloudwatch_conn.get_metric_statistics( Namespace='AWS/Billing', MetricName='EstimatedCharges', Period=86400, StartTime=last_date + " 00:00:00", EndTime=last_date + " 23:59:59", Statistics=['Maximum'], Dimensions=get_demesion ) for info in data['Datapoints']: return info['Maximum'] # ==== AWSのメトリックのサービスリストを取得する ==== # もうちょっと良い書き方が無いものか… service_list = [] service_value = [] json_value = cloudwatch_conn.list_metrics() for attr1 in json_value.get('Metrics'): for attr2 in attr1.get('Dimensions'): if attr2.get('Name') == "ServiceName": service_list.append(attr2.get('Value')) # ==== サービス別の金額を取得する ==== for service in service_list: service_value.append(get_value(service)) # ==== トータルの金額を取得する ==== total_value = get_value('ALL') # ==== SlackへPostする ==== SLACK_TEXT='昨日までのAWSの利用料金は$' + str(total_value) + 'になります' slack=slackweb.Slack(url=SLACK_WEBHOOK) attachments=[] attachment={'pretext': '各サービス別の利用料金','fields': []} for var in range(0, len(service_list)): item={'title': service_list[var] ,'value': '$' + str(service_value[var]) ,'short': "true"} attachment['fields'].append(item) attachments.append(attachment) slack.notify(text=SLACK_TEXT, channel=SLACK_CHANNEL, username=SLACK_USER, attachments=attachments)

以下のように出力される。