🐴

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は、アカウントにログインしている定で話を進めていきます。

  1. チャンネル設定画面を開きます
  2. 連携サービスをクリックし「ウェブフックを作成」を押します
  3. 新しいウェブフック」を押します
  4. 新規で作成されたウェブフックのURLをコピーします。
    これで、Discordの準備は終わりとなります

IAMロールの作成(Lambda用)

  1. AWS側でIAMロールの作成を押します
  2. エンティティは、「AWSのサービス」を選択、ユースケースは「Lambda」を選択
  3. 許可ポリシーの追加について今回は、何も選択せず次に行きます。
  4. その後に、適当なロール名を付けて作成
  5. 作成したロールの詳細画面で、「インラインポリシーを作成」を選択
  6. ポリシーエディタをJSONに選択し以下のJSONを追加して保存する
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ce:GetCostAndUsage"
      ],
      "Resource": "*"
    }
  ]
}

これでIAMの作成・設定は、完了です。

CostExplorerを有効にする

CostExplorerを有効して、コストを取得したいと思います。[

  1. 請求とコスト管理」を検索して開きます
  2. 左のメニューから「CostExplorer」を開きます
  3. 初めて開く方だと「AWS コスト管理へようこそ
    これは初めての訪問であるため、コストと使用状況のデータを準備するには時間がかかります。24 時間後にもう一度確認してください。」と表示されるので、しばらく待ちます
  4. CostExplorerの画面で「有効化」を押して完了です

※もしかしたら、「有効化」をする必要はないかもしれないです。

Lambdaの設定・実装(Python)

  1. 関数の作成
  • 関数名: NotifyAwsCost
  • ランタイム: Python 3.13
  • 実行ロール: デフォルトの実行ロールを変更を選択して、既存のロールを使用するを選択して先ほど作成したIAMロールを指定
    作成を選択
  1. コードの実装
lambda_function.py
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')
    }

  1. 環境変数の設定
    ・Lambdaのタブから「設定」を選択し、次に環境変数を選択
    ・「キー」:「DISCORD_WEBHOOK_URL」、「値」:コピーしたWebhook URLを貼り付け

EventBridge の設定

  1. EventBridge スケジュール」を選択し、ルールを作成
  2. 定期的なスケジュールを選択
  3. EventBridge スケジュールの設定
    スケジュール名: NotifyCostWeekly
    スケジュール: cron(0 9 ? * 1 *) → 毎週月曜9:00 UTC実行
    ターゲット: Lambda関数を選択(NotifyAwsCost)
    その中から、作成した「NotifyAwsCost」を選択
  1. 設定については、何も設定せずEventBridgeを作成
    これで完了になります。

これで、イベントで設定した時間になるとAWSのコストが送られてくると思います。

最後に

今回は、AWSのコストをDiscordで通知する機能を作成しました。
応用として、
・DynamoDB に「前回通知した金額」を保存し、2,000円以上増えたら通知
・Slack にも通知可能(Webhookを切り替えるだけ)
などしてみるのもいいかもしれません。

Discussion