0
1

CloudWatch Alarm もしくは EventBridge から SNS に通知した時の内容を整理してみた

Last updated at Posted at 2024-02-22

CloudWatch Alarm からの通知

SNS

次の通り、SNS トピックを用意しておきます。

スクリーンショット 2024-02-19 11.22.35.png

CloudWatch アラーム

CloudWatch アラームで先程作成した SNS を通知の送信先としておきます。

スクリーンショット 2024-02-19 15.46.23.png

スクリーンショット 2024-02-19 15.46.41.png

通知内容

ECS のタスクを意図的に 3 回連続で 1 にして、通知してみます。

CloudWatch アラーム → SNS → Email に通知した場合

スクリーンショット 2024-02-19 16.19.29.png

CloudWatch アラーム → SNS → Chatbot → Slack に通知した場合

スクリーンショット 2024-02-19 18.33.20.png

CloudWatch Alarm → Lambda → SNS に通知した場合

スクリーンショット 2024-02-20 2.10.51.png

ちなみにここでは補足ですが、CloudWatch Alarm のアクションとして直接 Lambda を指定することができるようになりました。

そのため、CloudWatch Alarm → Lambda → SNS のようにし、Lambda で簡易的にカスタマイズして通知しています。

CloudWatch Alarm からは次のようなイベントログです。

{
	"source": "aws.cloudwatch",
	"alarmArn": "arn:aws:cloudwatch:ap-northeast-1:123456789012:alarm:Error_ServiceA_Alarm",
	"accountId": "123456789012",
	"time": "2024-02-19T15:19:28.025+0000",
	"region": "ap-northeast-1",
	"alarmData": {
		"alarmName": "Error_ServiceA_Alarm",
		"state": {
			"value": "ALARM",
			"reason": "Threshold Crossed: 1 out of the last 1 datapoints [1.0 (19/02/24 15:17:00)] was less than or equal to the threshold (1.0) (minimum 1 datapoint for OK -> ALARM transition).",
			"reasonData": "{\"version\":\"1.0\",\"queryDate\":\"2024-02-19T15:19:28.022+0000\",\"startDate\":\"2024-02-19T15:17:00.000+0000\",\"statistic\":\"Sum\",\"period\":60,\"recentDatapoints\":[1.0],\"threshold\":1.0,\"evaluatedDatapoints\":[{\"timestamp\":\"2024-02-19T15:17:00.000+0000\",\"sampleCount\":1.0,\"value\":1.0}]}",
			"timestamp": "2024-02-19T15:19:28.025+0000"
		},
		"previousState": {
			"value": "OK",
			"reason": "Threshold Crossed: 1 out of the last 1 datapoints [2.0 (19/02/24 15:00:00)] was not less than or equal to the threshold (1.0) (minimum 1 datapoint for ALARM -> OK transition).",
			"reasonData": "{\"version\":\"1.0\",\"queryDate\":\"2024-02-19T15:02:32.938+0000\",\"startDate\":\"2024-02-19T15:00:00.000+0000\",\"statistic\":\"Sum\",\"period\":60,\"recentDatapoints\":[2.0],\"threshold\":1.0,\"evaluatedDatapoints\":[{\"timestamp\":\"2024-02-19T15:00:00.000+0000\",\"sampleCount\":1.0,\"value\":2.0}]}",
			"timestamp": "2024-02-19T15:02:32.939+0000"
		},
		"configuration": {
			"description": "ECSのタスクが3回連続で1以下になりました。",
			"metrics": [
				{
					"id": "92c6e0f3-9271-49e7-c4d9-93f5170897f5",
					"metricStat": {
						"metric": {
							"namespace": "ECS/ContainerInsights",
							"name": "RunningTaskCount",
							"dimensions": {
								"ServiceName": "ecs-svc",
								"ClusterName": "ecs-cluster"
							}
						},
						"period": 60,
						"stat": "Sum"
					},
					"returnData": true
				}
			]
		}
	}
}

CloudWatch Alarm からのイベントログを元に、Lambda は次の通り作成しています。

import os
import json
import boto3
from datetime import datetime, timezone, timedelta

def lambda_handler(event, context):
    # SNS トピックの ARN
    sns_topic_arn = os.environ['SNS_TOPIC_ARN']

    # CloudWatch アラームイベントから関連情報を抽出
    alarm_name = event['alarmData']['alarmName']
    alarm_reason = event['alarmData']['state']['reason']
    region = event['region']
    timestamp_utc = event['alarmData']['state']['timestamp']
    description = event['alarmData']['configuration']['description']

    # UTC のタイムスタンプを日本時間に変換
    timestamp_utc = datetime.strptime(timestamp_utc, '%Y-%m-%dT%H:%M:%S.%f+0000')
    timestamp_jst = timestamp_utc + timedelta(hours=9)  # JST (UTC + 9 hours)

    # SNS へ送信するメッセージを作成
    message = f"アラーム名: {alarm_name}\n"\
              f"理由: {alarm_reason}\n"\
              f"リージョン: {region}\n"\
              f"タイムスタンプ: {timestamp_jst.strftime('%Y-%m-%d %H:%M:%S')} (JST)\n"\
              f"説明: {description}"

    # SNS へ送信する Subject を設定
    subject = alarm_name

    # SNS にメッセージを送信
    sns_client = boto3.client('sns')
    sns_client.publish(
        TopicArn=sns_topic_arn,
        Message=message,
        Subject=subject
    )

EventBridge からの通知

EventBridge

イベントパターンは次の通り、alarmName が Error_ServiceA から始まる CloudWatch アラームのみに限定して通知することとします。

イベントパターン
{
  "source": ["aws.cloudwatch"],
  "detail-type": ["CloudWatch Alarm State Change"],
  "detail": {
    "alarmName": [{
      "prefix": "Error_ServiceA"
    }],
    "state": {
      "value": ["ALARM"]
    }
  }
}

通知内容

EventBridge → SNS → Email に通知した場合

スクリーンショット 2024-02-22 15.03.09.png

今回は、Lambda ではなく EventBridge の入力トランスフォーマーを使ってメッセージの内容を変換しています。
ただし、EventBridge のターゲット入力トランスフォーマーからは Subject が変換できるわけではないので、Subject も変更したい場合や、時刻を日本時間にしたい場合などは、Lambda をかます必要がありそうです。
スクリーンショット 2024-02-22 14.22.47.png

スクリーンショット 2024-02-22 14.45.40.png

EventBridge → SNS → Chatbot → Slack に通知した場合

スクリーンショット 2024-02-22 21.39.44.png

ここでも、EventBridge の入力トランスフォーマーを使っています。

スクリーンショット 2024-02-22 14.22.47.png

スクリーンショット 2024-02-22 21.37.03.png

詳しくは以下の方の記事とドキュメントを参考にしてみて下さい。

なお、入力トランスフォーマーを利用しなかった場合は、Slack に通知が飛びませんでした。
Chatbot のメトリクスを確認してみると、UnsupportedEvents が上がっています。
これは、サポートされていないイベントまたはメッセージが試行された数のようです。

スクリーンショット 2024-02-22 17.05.41.png

ちなみに、サポートされている GuardDuty イベントを通知した場合は、入力トランスフォーマー無しに通知することができました。

スクリーンショット 2024-02-22 17.00.28.png

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1