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