最近、Cost Explorer APIというものが新しくリリースされ、請求ダッシュボードから見られるコストが取得できるようになりました。
「Introducing the AWS Cost Explorer API」
これを使用し、Serverless FrameworkでEC2やCloudFrontなど各サービス毎のコストを算出してみます。
serverless.yml
service: cost-checker
provider:
name: aws
runtime: nodejs6.10
region: us-east-1
iamRoleStatements:
- Effect: Allow
Action:
- ce:GetCostAndUsage
Resource: "*"
functions:
costCheck:
handler: cost.check
events:
- schedule: cron(0 1 * * ? *)
timeout: 300
Cost Explorer API
はバージニア北部でしか使えないため region: us-east-1
を指定しdeployします。
cronはUTC表記のため、今回は日本時間の朝10時にCloudWatchEventsでLambdaが実行されます。
Cost Explorer API
const AWS = require('aws-sdk');
const costexplorer = new AWS.CostExplorer();
module.exports.check = () => {
const params = {
Granularity: 'DAILY',
Metrics: [ 'UnblendedCost' ],
GroupBy: [{
Type: 'DIMENSION',
Key: 'SERVICE',
}],
TimePeriod: {
Start: '2017-12-07',
End: '2017-12-08',
},
};
costexplorer.getCostAndUsage(params, (err, data) => {
if (err) {
console.error(err, err.stack);
return;
}
console.log(data);
});
};
これだけで2017-12-07
の各コストが取得できます。
細かいAPIの使い方はこちら
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CostExplorer.html
動的に日付を取得する
これだけでは、2017-12-07
の分しか取得できないため、TimePeriodを動的に指定できるようにします。
const _ = require('lodash');
const now = new Date();
const start = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
const end = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const TimePeriod = {
Start: `${start.getFullYear()}-${_.padStart(start.getMonth() + 1, 2, 0)}-${_.padStart(start.getDate(), 2, 0)}`,
End: `${end.getFullYear()}-${_.padStart(end.getMonth() + 1, 2, 0)}-${_.padStart(end.getDate(), 2, 0)}`,
};
now.getDate() - 1
で実行日の前日を取得、この方法であれば月をまたいだときも日付を自動で生成してくれます。
また、lodashを使い_.padStart()
で1桁の場合でも簡単に0
で埋めることができます。
Slackに送る
かなり雑ですが、costexplorer.getCostAndUsage()
で取得した値を、Slackのmessage apiのattachments.fieldsに詰めて送信しています。
const costs = [];
_.each(data.ResultsByTime, (item) => {
_.each(item.Groups, (group) => {
costs.push({
serviceName: _.head(group.Keys),
value: _.round(group.Metrics.UnblendedCost.Amount * 120, 2),
});
});
});
const message = {
username: 'コストさん',
channel: '#cost',
text: `${TimePeriod.Start}のコストです。:money_with_wings:`,
attachments: [
{
fields: _.map(costs, (item) => {
return {
title: item.serviceName,
value: item.value,
short: true,
}
});,
}
],
};
slack.post(message);
金額はドルで返ってくるので、1ドル120円換算にして、小数点2位まで表示
おわり
実際のところ、デイリーでコストを出しても毎日のアクセス数の上下で変わってくるので、よくわからないw
でも、一気にコストを削ったときにこうして見られるのは楽しい。一時的に使ったサーバーを消し忘れたとか、設定のミスとかもこういったレポートで、すぐに気がつけるんじゃないかなーと思います。
何よりメンバーにコスト感が生まれるし、どのAWSサービス使ってるかわかって良い。
Cost Explorer APIは1コール$0.01と結構お高い額を請求されます。
基本的に乱打するものではないと思いますが注意!