AWS Lambda + EventBridgeで毎週AWSのコストをDiscord通知する機能を作成してみた【無料枠で完結】
はじめに
最近、経験の浅いLambdaについて書くことがあったので、学習も込めて初心者の方にも挫折しないような記事を執筆できればと思います。
そこで皆さんAWSの利用料金って、気づいたら想定以上になっている方もいるのではないでしょうか
- AWS Budgetsでメール通知はできるけど、SlackやDiscordで柔軟に通知したい
- 週に1回、定期的に「今月いくら使ってるか」を見たい
そこで、AWSのコストを毎週Discordに通知する自動システムを作ってみました。
しかも、すべて無料枠で運用が可能です
今回の記事では、上記のような悩みを抱えている方と、これからAWSやLambdaを扱う技術について学びたい方といったAWS初心者向けの記事になっております。
扱うサービス一覧について
Lambdaとは
AWS Lambda を使用すると、サーバーをプロビジョニングまたは管理することなくコードを実行できるものです。
いわゆる、サーバーレスなのです。(AWSが管理してくれる)
EventBridgeとは
Amazon EventBridge は、コードを記述することなく、AWS サービス、独自のアプリケーション、Software as a Service (SaaS) アプリケーションのデータの変更に対するリアルタイムアクセスを提供するサービスです。
CostExplorerとは
Cost Explorerとは、AWSが提供するコスト管理サービスの一つで、AWSの利用料金と使用状況を可視化し、分析するためのツールです。
無料利用することができます。※Cost Anomaly Detectionは別です
各サービスの無料枠
| サービス名 | 無料枠 |
|---|---|
| Lambda | 100万回/月 |
| EventBridge | 100,000イベント/月 |
| Cost Explorer API | 無料 |
| Discord Webhook | 無料 |
準備
Discord Webhookの取得
DiscordのWebhookを取得したいと思います。
Discordは、アカウントにログインしている定で話を進めていきます。
- チャンネル設定画面を開きます
- 連携サービスをクリックし「ウェブフックを作成」を押します
- 「新しいウェブフック」を押します
- 新規で作成されたウェブフックのURLをコピーします。
これで、Discordの準備は終わりとなります
IAMロールの作成(Lambda用)
- AWS側でIAMロールの作成を押します
- エンティティは、「AWSのサービス」を選択、ユースケースは「Lambda」を選択
- 許可ポリシーの追加について今回は、何も選択せず次に行きます。
- その後に、適当なロール名を付けて作成
- 作成したロールの詳細画面で、「インラインポリシーを作成」を選択
- ポリシーエディタをJSONに選択し以下のJSONを追加して保存する
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ce:GetCostAndUsage"
],
"Resource": "*"
}
]
}
これでIAMの作成・設定は、完了です。
CostExplorerを有効にする
CostExplorerを有効して、コストを取得したいと思います。[
- 「請求とコスト管理」を検索して開きます
- 左のメニューから「CostExplorer」を開きます
- 初めて開く方だと「AWS コスト管理へようこそ
これは初めての訪問であるため、コストと使用状況のデータを準備するには時間がかかります。24 時間後にもう一度確認してください。」と表示されるので、しばらく待ちます - CostExplorerの画面で「有効化」を押して完了です
※もしかしたら、「有効化」をする必要はないかもしれないです。
Lambdaの設定・実装(Python)
- 関数の作成
- 関数名: NotifyAwsCost
- ランタイム: Python 3.13
-
実行ロール: デフォルトの実行ロールを変更を選択して、既存のロールを使用するを選択して先ほど作成したIAMロールを指定
作成を選択
- コードの実装
import os
import json
import boto3
import requests
from datetime import datetime
# Lambdaの環境変数からWebhook URLを取得
DISCORD_WEBHOOK_URL = os.environ.get("DISCORD_WEBHOOK_URL")
def lambda_handler(event, context):
# Cost Explorer API を使うクライアントの作成
client = boto3.client('ce')
now = datetime.utcnow()
start = now.replace(day=1).strftime('%Y-%m-%d')
end = now.strftime('%Y-%m-%d')
# 今月のコストを月単位で取得
response = client.get_cost_and_usage(
TimePeriod={
'Start': start,
'End': end
},
Granularity='MONTHLY',
# 通常の利用料金(割引適用前)
Metrics=['UnblendedCost']
)
# APIのレスポンスから 課金金額(USD) を抽出・数値に変換
amount = float(response['ResultsByTime'][0]['Total']['UnblendedCost']['Amount'])
# Discordで使えるメッセージを生成
message = {
"content": f"💸 今月のAWSコストは **{amount:.2f} USD** です({now.strftime('%Y-%m-%d')} 時点)"
}
# requests.post() で Discord Webhook に通知を送信
# content-type: application/json で形式を指定
requests.post(DISCORD_WEBHOOK_URL, data=json.dumps(message), headers={'Content-Type': 'application/json'})
# Lambdaが正常終了した時のレスポンス
return {
'statusCode': 200,
'body': json.dumps('Success lambda')
}
- 環境変数の設定
・Lambdaのタブから「設定」を選択し、次に環境変数を選択
・「キー」:「DISCORD_WEBHOOK_URL」、「値」:コピーしたWebhook URLを貼り付け
EventBridge の設定
- 「EventBridge スケジュール」を選択し、ルールを作成
- 定期的なスケジュールを選択
- EventBridge スケジュールの設定
・スケジュール名: NotifyCostWeekly
・スケジュール: cron(0 9 ? * 1 *) → 毎週月曜9:00 UTC実行
・ターゲット: Lambda関数を選択(NotifyAwsCost)
その中から、作成した「NotifyAwsCost」を選択
- 設定については、何も設定せずEventBridgeを作成
これで完了になります。
これで、イベントで設定した時間になるとAWSのコストが送られてくると思います。
最後に
今回は、AWSのコストをDiscordで通知する機能を作成しました。
応用として、
・DynamoDB に「前回通知した金額」を保存し、2,000円以上増えたら通知
・Slack にも通知可能(Webhookを切り替えるだけ)
などしてみるのもいいかもしれません。
Discussion