はじめに
AWSには「CostExplorer」というAWSのコスト関連を管理&分析してくれるサービスがあります。
このサービスで現在のAWS使用料も把握することもできます。
私はプライベートで色々試すことが多いので、常に使用料を把握しておきたいのですが、確認の度にAWSにログインするのがとても面倒でした。
なので、毎日slackに使用料を通知するようにしました。
やりたいこと
LambdaとEventBridgeを使って、月初からその日までの合計使用料を毎日0時にslackに通知する
事前準備
- 通知するslackチャンネルを作成しておく
- Incoming Webhookの設定を行い、URLを取得しておく
【2020年度版】Slack通知はSlack AppのIncoming Webhooksを使おう!やり方を解説
やってみる
1. Lambda関数を作成
「CostExplorerから今月の使用料を取得して、slackにそのデータを通知する」という内容でLambda関数で作成します。
「名前」と「利用する言語」を入力して、Lambda関数を作成
以下のように関数のコードを編集
from datetime import datetime
import json
import os
import urllib
import boto3
SLACK_WEBHOOK_URL = "https://hooks.slack.com/services/YYYYYY/XXXXXXXX" # slackのwebhook url
SLACK_CHANNEL_NAME = "#notice_aws_cost" # 通知先のslackチャンネル名
def lambda_handler(event, context):
today = datetime.now() # UTC時間
# Cost Explorerから今月の使用料を取得
client = boto3.client('ce')
response = client.get_cost_and_usage(
TimePeriod={
'Start': str(today.strftime('%Y-%m')) + '-01',
'End': today.strftime('%Y-%m-%d')
},
Granularity='MONTHLY',
Metrics=[
'AmortizedCost'
]
)
billing_dollers = response["ResultsByTime"][0]["Total"]["AmortizedCost"]["Amount"]
msg = f"""{today.strftime("%Y/%m/%d")}時点での今月の合計請求額をお知らせします。
合計請求額:{billing_dollers} USD"""
post_slack(msg)
def post_slack(msg):
# メッセージデータを作成
post_data = {
"username": "noticeBot", #ユーザー名
"icon_emoji": ":money_with_wings:", #アイコン
"text": msg, #メッセージ(※メンションを付与してる)
"channel": SLACK_CHANNEL_NAME #チャンネル
}
encode_post_data = ("payload=" + json.dumps(post_data)).encode('utf-8')
# Request(post)を作成
request = urllib.request.Request(
SLACK_WEBHOOK_URL,
data=encode_post_data,
method="POST"
)
# 送信
urllib.request.urlopen(request)
以下、コード内容の補足説明
# Cost Explorerから今月の使用料を取得
client = boto3.client('ce')
response = client.get_cost_and_usage(
TimePeriod={
'Start': str(today.strftime('%Y-%m')) + '-01',
'End': today.strftime('%Y-%m-%d')
},
Granularity='MONTHLY',
Metrics=[
'AmortizedCost'
]
)
billing_dollers = response["ResultsByTime"][0]["Total"]["AmortizedCost"]["Amount"]
CostExplorerのGetCostAndUsageというAPIを利用して、今月の1日から今日までの合計使用料を取得してます。
今回は月の使用料を取得してますが、日ごとの使用料も取得できます。また、サービスの合計ではなく各々のサービス使用料なども取得することができます。
GetCostAndUsage - AWS Cost Explorer Service
Serverlessで日々のAWSコストを算出する
def post_slack(msg):
# メッセージデータを作成
post_data = {
"username": "noticeBot", #ユーザー名
"icon_emoji": ":money:", #アイコン
"text": msg, #メッセージ(※メンションを付与してる)
"channel": SLACK_CHANNEL_NAME #チャンネル
}
encode_post_data = ("payload=" + json.dumps(send_data)).encode('utf-8')
# Request(post)を作成
request = urllib.request.Request(
SLACK_WEBHOOK_URL,
data=encode_post_data,
method="POST"
)
# 送信
urllib.request.urlopen(request)
slackにメッセージを送信する関数です。
SLACK_CHANNEL_NAME
、SLACK_WEBHOOK_URL
変数には、各自適した値を代入してください。
2. IAM Roleにポリシーを追加
Lambdaを作成すると自動でIAM Roleも一緒に作成されます。
そのIAM Roleには、Cost ExplorerのGetCostAndUsageの利用権限が付与されていません。
今の状態でLambdaを実行するとエラーになりますので、権限を付与します。
Lambdaのアクセス権限タブを開き、実行ロールのリンクにアクセス
インラインポリシーの追加
以下のようにJSONを記述し、名前をつけて作成
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ce:GetCostAndUsage",
"Resource": "*"
}
]
}
3. EventBridgeルールを作成
Lambda関数を作成したことで、使用料をslackに通知できるようになりました。
しかし、Lambdaには定期実行という仕組みがないので、毎日0時に実行することはできません。
それを実現するためにEventBridge ルールを作成します。
EventBridgeとは簡単に言うと、何かイベントが発火したらそれをトリガーにして、予め設定してるAWSリソースを実行してくれるサービスです。
Amazon EventBridge とは - Amazon EventBridge
EventBridge ルールを以下の設定で作成
これで毎日0時にAWSの使用料がslackに通知されるようになりました。
注意
cron式に「0 0 * * ? *」ではなく「0 15 * * ? *」と指定してるのは、cronが東京時間(UTC+9)ではなく標準時間(UTC+0)で動くので帳尻を合わせてます。
最後に
実はこのプログラム、実行されるたびに$0.01課金されます。
(CostExplorerのAPIを叩くときに$0.01のコストが発生)
無料で似たような事をしたいという方は、Budgetsを調べてみてください。