【AWS無料枠活用】CloudWatchアラームをLambdaで通知
やりたいこと
CloudWatchアラームの状態変化をLambdaで通知してみます。
どちらかというと個人勢向けで、できる限りお金をかけずに実現することを目指します。
前提
今回はAWSの無料枠を最大限使っていきます。
無料利用枠の詳細は「AWSクラウド無料利用枠の常に無料」で確認しています。
無料利用枠とは言っても条件には何種類かあり、一定期間経つと有料に切り替わったり、一定数使用すると有料に切り替わるものがありますので、条件については要確認です。
下記が今回使用するサービスおよび無料の条件です。
- Amazon CloudWatch
- 10 カスタムメトリクスおよび 10 アラーム
- 100 万件の API リクエスト
- 5 GB のログデータの取り込みおよび 5 GB のログデータのアーカイブ
- 毎月最大 50 メトリクスのダッシュボード 3 個
- Lambda
- 1,000,000 件/月の無料リクエスト
- 1 か月あたり最大 320 万秒のコンピューティング時間
※2025年6月時点
Lambdaはそこまで使用するつもりはないので無料の想定ですが、CloudWatchは100万APIリクエストを超えればいずれ請求が発生すると思います。
条件や対象サービスは常に変わりゆくので、常に確認することをおすすめします。
設定方法
Lambda
特に突出した設定はなく、Node.jsでLambda関数を作成します。
このLambda関数はCloudWatchから呼ばれ、アラームの状態を通知する関数となります。
今回は例としてDiscordのWebhookを使っていますが、そこはご自身の使いたいSNSに置き換えてください。
※大体やり方は似たような感じかと思います
/* global fetch */
export const handler = async (event, context, callback) => {
// 状態取得
const isAlarm = event?.alarmData?.state?.value === "ALARM";
// 通知内容作成
const messages = [
"<@12345678901234567890>",
`ヘルスチェックが${isAlarm ? "失敗" : "成功"}しました`,
"```",
JSON.stringify(event, null, "\t"),
"```",
];
// fetchで通知
const webhook = "https://discord.com/api/webhooks/1111111112222222222/XXXXXXXXXXX";
await fetch(webhook, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
content: messages.join("\n"),
}),
});
};
引数のevent
CloudWatchから呼ばれた場合、引数のeventには以下のような情報が入ります。
{
"source": "aws.cloudwatch",
"alarmArn": "arn:aws:cloudwatch:ap-northeast-1:123456789012:alarm:notify-health-check",
"accountId": "123456789012",
"time": "2025-06-26T14:25:09.889+0000",
"region": "ap-northeast-1",
"alarmData": {
"alarmName": "notify-health-check",
"state": {
"value": "ALARM",
"reason": "Threshold Crossed: 1 out of the last 1 datapoints [1.0 (26/06/25 14:20:00)] was less than the threshold (2.0) (minimum 1 datapoint for OK -> ALARM transition).",
"reasonData": "{\"version\":\"1.0\",\"queryDate\":\"2025-06-26T14:25:09.888+0000\",\"startDate\":\"2025-06-26T14:20:00.000+0000\",\"statistic\":\"Average\",\"period\":300,\"recentDatapoints\":[1.0],\"threshold\":2.0,\"evaluatedDatapoints\":[{\"timestamp\":\"2025-06-26T14:20:00.000+0000\",\"sampleCount\":15.0,\"value\":1.0}]}",
"timestamp": "2025-06-26T14:25:09.889+0000"
},
"previousState": {
"value": "OK",
"reason": "Threshold Crossed: 1 out of the last 1 datapoints [1.0 (13/05/25 00:06:00)] was not less than the threshold (1.0) (minimum 1 datapoint for ALARM -> OK transition).",
"reasonData": "{\"version\":\"1.0\",\"queryDate\":\"2025-05-13T00:11:21.055+0000\",\"startDate\":\"2025-05-13T00:06:00.000+0000\",\"statistic\":\"Average\",\"period\":300,\"recentDatapoints\":[1.0],\"threshold\":1.0,\"evaluatedDatapoints\":[{\"timestamp\":\"2025-05-13T00:06:00.000+0000\",\"sampleCount\":15.0,\"value\":1.0}]}",
"timestamp": "2025-05-13T00:11:21.057+0000"
},
"configuration": {
"metrics": [
{
"id": "11111111-xxxx-yyyy-zzzz-000000000000",
"metricStat": {
"metric": {
"namespace": "AWS/Route53",
"name": "HealthCheckStatus",
"dimensions": {
"HealthCheckId": "22222222-xxxx-yyyy-zzzz-000000000000"
}
},
"period": 300,
"stat": "Average"
},
"returnData": true
}
]
}
}
}
通知に含めたい情報がありましたら、event変数から取得してください。
CloudWatch
今回の例ではRoute53のヘルスチェックを監視するアラームを作成します。
なのでメトリクスはご自身のアラームを出したいサービスをご指定ください。
アクションにLambda関数を設定することがポイントです。
メトリクスと条件の指定 - オプション
メトリクス
ここはご自身にあったメトリクスをご指定ください。
例ではRoute53のヘルスチェックを監視するメトリクスを指定しています。
条件
こちらもメトリクスにあった条件をご指定ください。
例ではヘルスチェックが失敗した場合にアラームを発報するようにしています。
アクションの設定 - オプション
Lambda アクション
アラーム状態になったときにLambda関数を実行してほしいので、
先ほど作成したLambda関数を選択します。
もしほかのアクションがデフォルトで設定されている場合、今回は不要なので削除してください。
※必要なら設定してください
アラームの詳細の追加 - オプション
名前と説明
アラームの名前を指定してください。
プレビューと作成 - オプション
設定内容に問題がなければ「アラームの作成」ボタンを押してアラームを作成します。
しっかりインフラを組み込みたい場合
個人向けであれば上記構成でいいかと思いますが、
しっかりインフラを組み込みたい場合は、流れの一例を載せておきます。
※一例として詳細は割愛しますので参考までに…
シンプルに通知
特に通知内容をいじらずに通知さえこればOKというイメージですね。
CloudWatchアラーム → Amazon SNS(メールの場合)
CloudWatchアラーム → Amazon SNS → Amazon Q Developer(SNSの場合)
通知内容をカスタマイズしてSNSへ通知
EventBridgeでアラーム状態の状態変化を検知、
かつ通知内容をカスタマイズして、SNSに連携してAmazon Qから通知される仕組みです。
CloudWatchアラーム → EventBridge → Amazon SNS → Amazon Q Developer
通知内容をカスタマイズしてメール送信
EventBridgeでアラーム状態の状態変化を検知、
かつ通知内容をカスタマイズして、Step Functionsへ連携、
メールは特殊な型なので、StepFunctionsでも変換をかけ、あとはSNSに連携して通知される仕組みです。
CloudWatchアラーム → EventBridge → Step Functions → Amazon SNS
まとめ
無料利用枠を最大限利用して通知をしてみました。
個人勢だと、少しでも節約したいですよね。
無料枠を用意してくれているAWSさん、本当に感謝です。
以上、ここまで見ていただきありがとうございます。
皆さまの快適な開発ライフに、ほんの少しでもお役に立てれば幸いです。