はじめに(注意)
この投稿は(お試しで)AIちゃんに、
作業内容をMD形式で出力してもらったものになります。
いけだの手によって、少しだけRvはされていますが、基本はそのままですので、
口調などが統一されていないなど、ある程度、ご容赦頂ければと思います。
🎯 目的
自分のAWSアカウントを久しぶりに使おうと思ったのですが、
アカウント作成から1年経過したため、無料枠がないことに気づきました。
いきなり高額請求!って言うのが嫌だったので、
AWSの月間利用料金が 35ドル (日本円で5000円) を超えた際に、
Discordに自動通知を送る仕組みを構築することにしました。
Discordを選択した理由は普段使いしているからであり、
皆さんに置かれましては、SMSやメール、LINEなど
お好きなサービスを利用してください。
以下から、AIちゃんの代筆
🛠 使用AWSサービス
- AWS Budgets:予算アラートの作成
- Amazon SNS:通知ルーティング
- AWS Lambda:通知処理(Webhook POST)
- IAMロール・環境変数:セキュリティ・保守性対応
✅ 全体構成イメージ
[ AWS Budgets(5000円超過) ]
↓ SNS通知
[ SNSトピック:budget-alert ]
↓ 通知
[ Lambda関数:NotifyAwsCostToDiscord ]
↓ Webhook POST
[ Discordチャンネル ]
✅ 構築ステップ一覧
1. Budgetsで予算アラートを作成
- AWSコンソール → 「請求ダッシュボード」 → 「予算」
- 「予算を作成」→「コスト予算」を選択
- 月額:5000円
- 通知タイプ:実際のコストが100%を超えたとき
- 通知先:SNSトピックを作成(例:
budget-alert
)
2. SNSトピックを作成
- サービス:Amazon SNS
- トピック名:
budget-alert
- タイプ:標準
- ARNを控えておく(LambdaやIAMで使用)
3. Lambda関数を作成
- 名前:
NotifyAwsCostToDiscord
- ランタイム:Python 3.x(例:Python 3.12)
- IAMロール:
AWSLambdaBasicExecutionRole
を付与
コード例:
import json
import urllib.request
import os
def lambda_handler(event, context):
message = event['Records'][0]['Sns']['Message']
webhook_url = os.environ.get("WEBHOOK_URL")
if not webhook_url:
raise Exception("WEBHOOK_URLが環境変数に設定されていません")
data = {
"content": f"💸 AWS月額コストが5000円を超えました!\n詳細: {message}"
}
headers = {
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0"
}
req = urllib.request.Request(
webhook_url,
data=json.dumps(data).encode("utf-8"),
headers=headers,
method="POST"
)
try:
with urllib.request.urlopen(req) as res:
print("送信成功:", res.read().decode())
except Exception as e:
print("送信失敗:", e)
4. Lambdaに環境変数を設定
- Lambdaの「構成」→「環境変数」→ 「編集」
- 以下を追加:
キー名 | 値(例) |
---|---|
WEBHOOK_URL |
https://discord.com/api/webhooks/... |
Webhook URLのハードコーディングを避け、セキュアに管理!
5. SNSとLambdaを連携(サブスクリプション)
- SNSトピック
budget-alert
→ 「サブスクリプションを作成」 - プロトコル:
AWS Lambda
- エンドポイント:Lambda関数名を選択
Lambdaの「アクセス権限」タブで、SNSからの
lambda:InvokeFunction
許可を確認(自動付与されることもあり)
6. テスト方法
✅ Lambda単体テスト(コード確認用)
{
"Records": [
{
"Sns": {
"Message": "テスト送信メッセージです"
}
}
]
}
✅ SNSからのテスト
- SNSトピック → 「メッセージを発行」
- 任意メッセージを入力 → Lambda経由でDiscordに通知されれば成功!
いけだコメント:
ここまでが通知機能作成の流れですが、
いけだはテスト通知してみる際に、下記エラーと遭遇したので、対策を実施。
(4. のコードには反映済み)
7. Cloudflareによる403対策
- DiscordのWebhookはCloudflareのWAFに守られている
- Pythonの
urllib
ではUser-Agent
がないと403 + code 1010 に!
headers = {
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0"
}
いけだコメント:
下記は任意項目です。
所属PJではよくやっていますし、今後改造して失敗したとき、サッと元に戻したかったので。
8. Lambdaのバージョン管理とエイリアス(任意)
操作 | 説明 | 料金 |
---|---|---|
バージョン発行 | 関数のスナップショット作成 | 無料 |
エイリアス作成 |
prod など名前付きポインタ |
無料 |
実行 | 通常通り課金される | 通常のLambda料金 |
いけだコメント:
SNSを使って通知を送るとき、
Lambdaなどでコケた場合の再送方法とかを知らなかったので、追加で質問、確認しました。
何も設定しなくても勝手に再送/リトライしてくれるみたいです。
9. SNSの自動リトライ仕様
内容 | 詳細 |
---|---|
最大回数 | 100回 |
最大期間 | 23日間 |
バックオフ | 指数バックオフ(時間ごとに遅くなる) |
手動再送 | 不要、自動で再送される |
課金 | 再送分もLambda/SNSの実行料金が発生 |
いけだコメント:
今は高額になりえるサービスを使っていませんが、
EC2とか、起動しっぱなしで超えた場合、止めるとか、
起動させないことってできるのか、調べてもらいました。
10. コスト制御と自動制限について(補足)
やりたいこと | 可能か? | 方法例 |
---|---|---|
5000円超過時に通知 | ✅ | Budgets + SNS |
自動でリソースを停止 | ✅ | Lambdaで EC2/BATCH などを stop |
IAM操作を制限する | ✅(自作) | Lambdaで IAM Policy を detach |
AWSが強制ブロックする | ❌ | 仕様上不可能(通知まで) |
個人利用かつ低額なら、通知だけで十分現実的&安全!
いけだコメント:
総評として、今回の対応についてと、今後の改造プランまで、まとめてもらってます。
AIちゃんはいい子いい子してくれるので、ほめられて伸びたいタイプにはおすすめです。
✅ 今回の構成は個人利用でも本番級!
- 安全:Webhookを環境変数で管理
- 安価:Lambda/SNS/Budgetは月額ほぼ無料枠範囲
- 柔軟:通知先(Discord → LINEなど)拡張可能
- 拡張性:月末レポート、週次アラートも可能
📌 今後の拡張アイデア
- LINE Notify対応
- 月末自動集計レポート
- 通知の装飾(emoji, embed形式など)
- AWS Cost Explorerからサービスごとの内訳取得
AIちゃん代筆終わり
終わりに
作業はAIちゃん(ChatGPT-4o)と二人三脚しました。
コードやエラーについてはサクッと作れる感じですね。
ただ(当たり前ですが)テキストベースでのやり取りである以上、この記事のようにAWS側のGUIベースの設定がし辛いですね。
いけだは作業イメージを補完するために、参考になるサイトをピックしてもらったりしました。
色々やってみたいこととかあるんですけど、一人だとやる気が出なかったりしたので、引き続きAIちゃんと勉強しながらモノづくりしようかなと思いました。
おわり