CPU使用率やリクエスト数のような「量」はCloudWatchの標準メトリクスで監視できる。 しかし運用で本当に知りたい「ECSタスクが異常停止した」「デプロイが失敗した」という出来事は、標準メトリクスには現れない。 本稿では、AWSの3サービスを直列に束ねてイベントをメトリクス化し、通常のアラーム運用に乗せる構成パターンを解説する。
1. 課題: 「量」は見えるが「出来事」が見えない
下3つはAWS内部でイベントとして発生している。EventBridgeにはこれらのイベントが流れているが、 イベントは「その瞬間に流れて消える」ものであり、そのままではアラームの対象にならない。 「過去5分間に何回発生したか」という数に変換して初めて、閾値監視ができる。
2. 構成: イベント → ログ → メトリクスのパイプライン
3つのサービスの役割分担は明確である。
この構成の利点は、メトリクス化と同時に調査用のログが残ることにある。 アラームが鳴った時、メトリクスは「何回起きたか」しか教えてくれないが、 CloudWatch Logsにはイベント本文(どのクラスタで、どんな理由で停止したか)がJSONで残っているため、そのまま原因調査に入れる。
3. 設計判断: なぜLambdaを使わないのか
イベントをメトリクス化する方法としては、EventBridgeからLambdaを起動してPutMetricDataを呼ぶ構成も考えられる。
あえてLambdaを使わない理由は次の通り。
監視基盤は「壊れにくいこと」が最優先である。コードを持たず、AWSのマネージド機能の直列接続だけで構成すれば、 監視基盤そのものの運用負荷をほぼゼロにできる。
4. 監視対象を宣言的に増やす
この構成をTerraformモジュールにする際は、「イベントパターン + メトリクス名 + ディメンション」の組をmapで受け取る形にすると、 監視対象の追加が宣言1つで済む。
# 概念例(汎用化した書き方)
|
monitoring_events = {
|
ecs_task_failed = {
|
event_pattern = {
|
source = ["aws.ecs"]
|
detail-type = ["ECS Task State Change"]
|
detail = {
|
lastStatus = ["STOPPED"]
|
stoppedReason = [{ "prefix" = "Essential container" }]
|
}
|
}
|
metric_name = "ECSTaskFailed"
|
dimensions = { ClusterName = "$.detail.clusterArn" }
|
}
|
deploy_failed = {
|
event_pattern = {
|
source = ["aws.codedeploy"]
|
detail-type = ["CodeDeploy Deployment State-change Notification"]
|
detail = { state = ["FAILURE"] }
|
}
|
metric_name = "CodeDeployFailed"
|
dimensions = { ApplicationName = "$.detail.application" }
|
}
|
} |
ポイントは2つ。
- イベントパターンはAWSが公式に定義している。「ECS Task State Change」等のイベント構造は各サービスのドキュメントに公開されており、
stoppedReasonのprefix一致で「コンテナ起因の停止だけ」を絞り込むような精密なフィルタが書ける - ディメンションはJSONPathでイベント本文から抽出する。クラスタ名やアプリケーション名をディメンションにしておけば、1つの仕組みで複数サービスを区別して監視できる
5. まとめ
「CPUは正常なのにサービスが動いていない」という状況の多くは、標準メトリクスの外側で起きた出来事が原因である。 イベントをメトリクスに変換する小さなパイプラインを1つ持っておくと、監視の空白地帯を宣言1つずつ埋めていける。
