FDシステム インフラ監視・アラート設計
1. 概要
1.1 目的
システムの可用性・性能・信頼性を維持・向上するための監視・アラート基準を定義し、運用を標準化する。
1.2 スコープ
対象サービス
- 外形監視: Cloudflare Synthetic Monitoring
- ロードバランサー: Application Load Balancer (ALB)
- コンピュート: ECS/Fargate
- データストア: RDS (PostgreSQL), ElastiCache (Redis)
対象環境
- infra-dev
- staging(developアカウント)
- production(AmazonConnectアカウント)
非対象
- 組織横断の共通基盤モニタリング(ネットワーク、IAM、監査ログ集約など)
- アプリケーション固有のメトリクス(APM、トレースなど)
1.3 前提条件
- 必須タグ:
env,service,teamを必須タグとする - ツール: Datadog / CloudWatch のいずれかまたは両方を使用
- 通知先: Slack
2. 監視戦略
2.1 基本原則
1. Golden Signals
全レイヤーを以下の4つの指標でカバーする:
- Latency (レイテンシ): リクエスト処理時間
- Traffic (トラフィック): リクエスト量
- Errors (エラー): エラー率
- Saturation (飽和): リソース使用率
2. ノイズ抑制
- 運用開始後の修正を前提とした適切な評価期間の設定
2.2 監視レイヤー
3. SLI/SLO定義
SLI/SLOは別途検討する。 (インフラ観点で信頼性を損なっている、または損なう可能性の状態を検知することを優先し設計・実装進める。)
4. 命名規則
4.1 基本原則
- 一貫性: 全監視リソースで統一した命名パターンを使用
- 可読性: 名前から監視対象とアラート内容が把握できること
- 検索性: 環境・サービス・コンポーネントでフィルタリング可能なこと
- 長さ: 過度に長くならないよう、略語と省略形を適切に使用
4.2 CloudWatch Alarm命名規則
構文
{service}-{env}-{component}-{metric}-{condition}要素説明
| 要素 | 説明 | 例 |
|---|---|---|
service | サービス名 | fd-system |
env | 環境識別子 | prod, stg, infra-dev |
component | AWS コンポーネント種別 | alb, ecs, rds, redis |
metric | メトリクス名(略語可) | cpu, memory, 5xx, 502, unhealthy, swap, storage |
condition | 閾値条件 | high, low, critical, medium |
命名例
| アラート種別 | CloudWatch Alarm名 | 説明 |
|---|---|---|
| ALB 502エラー | fd-system-prod-alb-502-critical | 本番環境のALB 502エラー急増 |
| ALB Target 5xx | fd-system-prod-alb-target-5xx-critical | 本番環境のバックエンド5xxエラー急増 |
| ALB Unhealthy Target | fd-system-prod-alb-unhealthy-target-high | 本番環境のUnhealthyターゲット増加 |
| ECS CPU使用率 | fd-system-prod-ecs-cpu-high | 本番環境のECS CPU使用率高騰 |
| ECS メモリ使用率 | fd-system-prod-ecs-memory-high | 本番環境のECS メモリ使用率高騰 |
| ECS タスク数 | fd-system-prod-ecs-running-count-low | 本番環境のECS実行タスク数不足 |
| RDS CPU使用率 | fd-system-prod-rds-cpu-high | 本番環境のRDS CPU使用率高騰 |
| RDS スワップ使用 | fd-system-prod-rds-swap-critical | 本番環境のRDSスワップ使用(Critical) |
| RDS ストレージ | fd-system-prod-rds-storage-critical | 本番環境のRDSストレージ枯渇 |
| RDS 接続数 | fd-system-prod-rds-connections-high | 本番環境のRDS接続数高騰 |
| Redis メモリ | fd-system-prod-redis-memory-critical | 本番環境のRedisメモリ枯渇 |
| Redis CPU | fd-system-prod-redis-cpu-high | 本番環境のRedis CPU使用率高騰 |
4.3 監視用EventBridge Rule命名規則
構文
{service}-{env}-{component}-{event-type}命名例
| イベント種別 | EventBridge Rule名 | 説明 |
|---|---|---|
| ECS デプロイ失敗 | fd-system-prod-ecs-deployment-failed | ECSサービスデプロイメント失敗 |
| ECS タスク停止(OOM) | fd-system-prod-ecs-task-oom | タスクがOutOfMemoryで停止 |
| ECS タスククラッシュ | fd-system-prod-ecs-task-crash | タスクが異常終了(exitCode≠0) |
4.4 Datadog Monitor命名規則
構文
{env}/{service}: {Component} {Metric} {Condition}要素説明
| 要素 | 説明 | 例 |
|---|---|---|
env | 環境識別子 | prod, stg, dev, infra-dev |
service | サービス名 | fd-system |
Component | コンポーネント(人間可読) | ALB, ECS, RDS, Redis, Cloudflare |
Metric | メトリクス(人間可読) | 502 Error, CPU Usage, Memory Usage |
Condition | 条件(人間可読) | Medium, High, Critical, Low |
命名例
| アラート種別 | Datadog Monitor名 | 説明 |
|---|---|---|
| 外形監視 | prod/fd-system: Cloudflare Endpoint Unreachable | エンドポイント到達不能 |
| ALB 502エラー | prod/fd-system: ALB 502 Error Spike | ALB 502エラー急増 |
| ALB Target 5xx | prod/fd-system: Target 5xx Error Rate > 1% | バックエンド5xxエラー率1%超過 |
| ECS CPU | prod/fd-system: ECS CPU High (> 70%) | ECS CPU使用率70%超過 |
| ECS メモリ | prod/fd-system: ECS Memory High (> 80%) | ECS メモリ使用率80%超過 |
| RDS スワップ | prod/fd-system: RDS Swap Usage Detected | RDSスワップ使用検知 |
| Redis メモリ | prod/fd-system: Redis Memory Critical (> 80%) | Redisメモリ使用率80%超過 |
4.5 SNS Topic命名規則
構文
{service}-{env}-alerts-{severity}命名例
| 重要度 | SNS Topic名 | 説明 |
|---|---|---|
| Critical | fd-system-prod-alerts-critical | Critical アラート通知先 |
| High | fd-system-prod-alerts-high | High アラート通知先 |
| Medium | fd-system-prod-alerts-medium | Medium アラート通知先(オプション) |
4.6 タグ付け規則
すべての監視リソース(CloudWatch Alarm、EventBridge Rule、SNS Topic、Datadog Monitor)には以下のタグを必須で付与します。
必須タグ
| タグキー | 説明 | 例 |
|---|---|---|
env | 環境識別子 | prod, stg, dev, infra-dev |
service | サービス名 | fd-system |
team | 担当チーム | sre, tob |
CloudWatch Alarm タグ例
resource "aws_cloudwatch_metric_alarm" "alb_502" {
alarm_name = "fd-system-prod-alb-502-critical"
# ... その他の設定 ...
tags = {
env = "prod"
service = "fd-system"
team = "sre"
component = "alb"
severity = "critical"
}
}Datadog Monitor タグ例
resource "datadog_monitor" "alb_502" {
name = "prod/fd-system: ALB 502 Error Spike"
# ... その他の設定 ...
tags = [
"env:prod",
"service:fd-system",
"team:sre",
"component:alb",
"severity:critical"
]
}4.7 命名規則の利点
- 検索性向上: タグとプレフィックスで環境・サービス単位でフィルタリング可能
- 可読性向上: 一目で監視対象とアラート内容を把握可能
- 自動化対応: 命名パターンが統一されているため、Terraformモジュール化が容易
- 運用負荷軽減: 命名ルールが明確なため、新規アラート追加時の迷いが減少
5. 監視対象とメトリクス
5.1 Cloudflare / 外形監視
監視対象エンドポイント
cp.fastdoctor.jpu.fastdoctor.jpbackend.fastdoctor.jpcable.fastdoctor.jp
監視項目
| 項目 | メトリクス | 閾値 | 重要度 | 考えられる影響 |
|---|---|---|---|---|
| エンドポイント可用性 | /status レスポンス | 200/201 | Critical | サービス全体が利用不可となり、全ユーザーがアクセスできない |
| レイテンシ | p95 応答時間 | < 1000ms | High | ユーザー体験の低下、タイムアウトエラーの増加 |
※ 閾値は運用しながら調整する
5.2 ALB / Target Group
監視対象サービス
fastdoctor-manager-prd-appcable-fdm-prd-app
監視項目
| カテゴリ | メトリクス | 説明 | 重要度 | 閾値 | 考えられる影響 |
|---|---|---|---|---|---|
| 可用性 | HTTPCode_ELB_502_Count | ALB起因の5xxエラー | Critical | > 5 (5分) | バックエンドへの接続不能により、サービス全体が停止 |
| エラー | HTTPCode_Target_5XX_Count | バックエンド5xxエラー | Critical | > 5 (5分) | アプリケーションレベルのエラーにより、特定機能が利用不可 |
| レイテンシ | TargetResponseTime (p95) | バックエンド応答時間 | High | > 800ms (5分) | 応答遅延によるユーザー体験の著しい低下 |
| 健康度 | UnHealthyHostCount | 異常なターゲット数 | High | > 0 (5分) | 冗長性の低下、障害発生時の影響拡大 |
※ 閾値は運用しながら調整する
補足
5xxエラーの主な原因
- ヘルスチェック失敗
- バックエンドタイムアウト
- Target Groupの全タスクが応答不能
- ECSタスクの起動遅延
5.3 ECS / Fargate
監視対象サービス (us-prod)
cable-fdm-us-prdfastdoctor-manager-us-prdmobakar-sync-worker-fdm-us-prdmobakar-sync-worker-fdm-us-prd-2mobakar-worker-fdm-us-prdmobakar-worker-fdm-us-prd-2worker-fastdoctor-manager-us-prd
監視項目
| カテゴリ | メトリクス | 説明 | 重要度 | 閾値 | 考えられる影響 |
|---|---|---|---|---|---|
| 飽和 | CPUUtilization (平均) | CPU使用率 | High | > 70% (5分) | レスポンスタイム増加、処理遅延の発生 |
| 飽和 | MemoryUtilization (平均) | メモリ使用率 | High | > 80% (5分) | メモリ不足によるパフォーマンス低下の予兆 |
| 追従性 | RunningTaskCount | 実行中タスク数 | Critical | < 1 (5分) | 処理能力不足、サービス停止の可能性 |
※ 閾値は運用しながら調整する
ECSイベント監視
| イベント | detail-type | 判定条件 | 重要度 |
|---|---|---|---|
| デプロイ失敗 | ECS Service Action | eventType=ERROR, eventName=SERVICE_DEPLOYMENT_FAILED | Critical |
| タスク起動失敗 | lastStatus=STOPPED, desiredStatus=RUNNING | Critical | |
| OOM | ECS Task State Change | stoppedReason contains "OutOfMemory" | Critical |
| アプリクラッシュ | ECS Task State Change | stoppedReason contains "Essential container", exitCode≠0 | Critical |
| ヘルスチェック失敗 | ECS Task State Change | stoppedReason contains "failed ELB health checks" | High |
| スケール失敗 | ECS Service Action | eventName=SERVICE_TASK_PLACEMENT_FAILURE | High |
(TBD)検証次第で判定条件に修正が入る可能性がある
EventBridgeパターン(例):
{
"source": ["aws.ecs"],
"detail-type": ["ECS Service Action"],
"detail": {
"eventType": ["ERROR"],
"eventName": ["SERVICE_DEPLOYMENT_FAILED"]
}
}5.4 RDS (PostgreSQL)
監視対象インスタンス
- プライマリ:
fastdoctor-manager-db1 - レプリカ:
fastdoctor-manager-db3fastdoctor-manager-db5fastdoctor-manager-db4(Osaka リージョン)
監視項目
| カテゴリ | メトリクス | 説明 | 重要度 | 閾値 | 考えられる影響 |
|---|---|---|---|---|---|
| CPU | CPUUtilization | CPU使用率 | High | > 80% (5分) | クエリ処理遅延、レスポンスタイムの増加 |
| メモリ | FreeableMemory | 空きメモリ | High | < 1GB | バッファキャッシュ不足によるディスクI/O増加、性能低下 |
| メモリ | SwapUsage | スワップ使用量 | Critical | > 100MB | 深刻なメモリ不足、クエリ処理の著しい遅延 |
| ストレージ | FreeStorageSpace | 空きディスク容量 | Critical | < 10GB | 書き込み不能、データベース停止の危険性 |
| 接続 | DatabaseConnections | アクティブ接続数 | High | > 最大の80% | 新規接続拒否、アプリケーションエラーの発生 |
| レイテンシ | ReadLatency | 読み取り遅延 | Medium | > 5ms | 読み取り処理の遅延によるページ表示速度の低下 |
| レイテンシ | WriteLatency | 書き込み遅延 | High | > 200ms | トランザクション処理の遅延、タイムアウトの増加 |
| レプリケーション | AuroraReplicaLag | レプリカ遅延 | High | > 5000ms | 読み取りレプリカでの古いデータ参照、整合性問題 |
※ 閾値は運用しながら調整する
イベント監視
Critical Events
RDS-EVENT-0004: インスタンスがシャットダウンRDS-EVENT-0006: インスタンスが再起動
5.5 Redis (ElastiCache)
監視対象クラスター
プロビジョンド
fastdoctor-manager-us-prd
Serverless
fdm-serverless- 注意: 現時点では監視不要だが、スロットリングやECPUコスト課題が顕在化した場合は監視を検討する
プロビジョンド監視項目
| カテゴリ | メトリクス | 説明 | 重要度 | 閾値 | 考えられる影響 |
|---|---|---|---|---|---|
| CPU | EngineCPUUtilization | CPU使用率 | High | > 80% (5分) | コマンド処理遅延、レスポンスタイムの増加 |
| メモリ | DatabaseMemoryUsagePercentage | メモリ使用率 | Critical | > 80% | エビクション発生、キャッシュミスの増加 |
| メモリ | SwapUsage | スワップ使用 | Critical | > 100MB | 深刻なメモリ不足、Redis性能の著しい低下 |
| パフォーマンス | CacheHitRate | キャッシュヒット率 | Medium | < 50% | データベース負荷増加、レスポンスタイム悪化 |
※ 閾値は運用しながら調整する
6. アラートポリシー
6.1 アラート重要度定義
| 重要度 | 説明 | 対応時間 | 通知先 |
|---|---|---|---|
| Critical | ユーザー影響あり、即時対応必要 | 5分以内 | Slack (notifications_server_prod)(今後オンコールを検討) |
| High | 潜在的な問題、早期対応推奨 | 60分以内 | Slack (notifications_server_prod) |
| Medium | 調査・傾向分析 | 営業時間内 | Slack (notifications_server_prod) |
| Low | 詳細ログ、診断情報 | 必要時のみ | ログのみ |
注意: 現状はSlack通知までの実装。将来的なオンコール対応体制については、別途検討・設計が必要 https://fastdoctor.atlassian.net/browse/SRE-1763
6.2 Criticalアラート
外形監視
| アラート名 | 条件 | 評価期間 | 理由 |
|---|---|---|---|
| エンドポイント到達不能 | /healthz が200/204以外 | 3回連続 | サービス全体停止 |
ALB層
| アラート名 | 条件 | 評価期間 | 理由 |
|---|---|---|---|
| ALB 502エラー急増 | HTTPCode_ELB_502_Count > 5 | 5分合計 | バックエンド到達不能 |
| Target 5xxエラー急増 | HTTPCode_Target_5XX_Count > 5 | 5分合計 | アプリケーション障害 |
ECS層
| アラート名 | 条件 | 評価期間 | 理由 |
|---|---|---|---|
| タスク数不足 | RunningCount < 1 | 5分継続 | サービス停止の可能性 |
| デプロイ失敗 | SERVICE_DEPLOYMENT_FAILED イベント | 即座 | デプロイ失敗 |
| タスク起動失敗 | lastStatus=STOPPED, desiredStatus=RUNNING | 即座 | リソース不足/設定エラー |
| OOMエラー | stoppedReason contains "OutOfMemory" | 即座 | メモリ不足 |
| アプリクラッシュ | stoppedReason contains "Essential container", exitCode≠0 | 即座 | アプリケーション異常終了 |
データストア層
| アラート名 | 条件 | 評価期間 | 理由 |
|---|---|---|---|
| RDSスワップ使用 | SwapUsage > 0 | 2分継続 | 深刻なメモリ不足 |
| RDSストレージ枯渇 | FreeStorageSpace < 10GB | 5分継続 | ディスク容量不足 |
| RDS再起動 | RDS-EVENT-0004, RDS-EVENT-0006 イベント | 即座 | 予期せぬ再起動/シャットダウン |
| Redisメモリ枯渇 | DatabaseMemoryUsagePercentage > 80% | 2分継続 | エビクション開始の危険性 |
| Redisスワップ使用 | SwapUsage > 100MB | 2分継続 | 深刻なメモリ不足 |
6.3 Highアラート
外形監視
| アラート名 | 条件 | 評価期間 | 対応 |
|---|---|---|---|
| レイテンシ劣化 | p95応答時間 > 1000ms | 5分継続 | パフォーマンス調査 |
ALB層
| アラート名 | 条件 | 評価期間 | 対応 |
|---|---|---|---|
| ALBレイテンシ劣化 | TargetResponseTime p95 > 800ms | 5分継続 | パフォーマンス調査 |
| UnHealthyホスト検出 | UnHealthyHostCount > 0 | 5分継続 | ヘルスチェック調査 |
ECS層
| アラート名 | 条件 | 評価期間 | 対応 |
|---|---|---|---|
| ECS CPU高止まり | CPUUtilization > 70% | 5分平均 | スケール検討 |
| ECS Memory高止まり | MemoryUtilization > 80% | 5分平均 | メモリ最適化 |
| ヘルスチェック失敗 | stoppedReason contains "failed ELB health checks" | 即座 | ヘルスチェック設定確認 |
データストア層
| アラート名 | 条件 | 評価期間 | 対応 |
|---|---|---|---|
| RDS CPU高負荷 | CPUUtilization > 80% | 5分平均 | クエリ最適化 |
| RDS空きメモリ低下 | FreeableMemory < 1GB | 5分平均 | メモリ最適化 |
| RDS接続数高止まり | DatabaseConnections > 最大の80% | 5分継続 | 接続プール設定確認 |
| RDS読み込み遅延 | ReadLatency > 5ms | 5分平均 | クエリ最適化 |
| RDS書き込み遅延 | WriteLatency > 200ms | 5分平均 | クエリ最適化 |
| RDSレプリカ遅延 | AuroraReplicaLag > 5000ms | 5分平均 | レプリケーション確認 |
| Redis CPU高負荷 | EngineCPUUtilization > 80% | 5分平均 | スケールアップ検討 |
| Redisキャッシュヒット率低下 | CacheHitRate < 50% | 5分平均 | キャッシュ戦略見直し |
6.4 アラート抑制・調整方針
初期設定の考え方
本ドキュメントで定義した閾値と評価期間は、初期値として設定します。運用開始後、実際のシステム動作とアラート発生状況を観察しながら、継続的に調整していく必要があります。
目的: 誤発報やノイズを防止し、正しく監視・アラートすることで、実効性の高い運用体制を確立する
運用開始後の調整プロセス
担当: 実装したオーナーチームが実施
1週目: 観察期間
- アラート発生状況の全記録(発生時刻、頻度、実際の影響)
- 誤検知(False Positive)の特定
- 見逃し(False Negative)の有無確認
- ノイズとなるアラートの洗い出し
2週目以降: 段階的調整
- 頻繁に発火するアラートの閾値緩和
- 重要なイベントを見逃しているアラートの閾値厳格化
- 評価期間の最適化(瞬間的なスパイクを除外)
- 抑制ルールの追加(定期処理、デプロイ時など)
月次レビュー: 定期見直し
- アラート発生傾向の分析
- 対応時間の実績確認
- 新規アラート追加の検討
- 不要になったアラートの無効化
調整判断基準
| 状況 | 対応 | 具体例 |
|---|---|---|
| 1時間に3回以上の誤検知 | 閾値を緩和、または評価期間を延長 | CPU 70% → 75%、5分 → 10分 |
| 重大インシデントを検知できず | 閾値を厳格化、または新規アラート追加 | メモリ 80% → 70% |
| 夜間の定期処理で毎日発火 | 時間帯による抑制設定 | 2:00-3:00はアラート無効化 |
| デプロイ時に必ず発火 | デプロイタグによる抑制 | deploy:in-progressタグで抑制 |
| 週末のメンテナンスで発火 | メンテナンスウィンドウ設定 | 土曜20:00-22:00は抑制 |
メンテナンスウィンドウ設定例
Datadog Downtime設定
downtime:
scope: "env:prod,service:fastdoctor-manager"
start: "2025-10-22T20:00:00+09:00"
end: "2025-10-22T22:00:00+09:00"
message: "定期メンテナンス: DBパッチ適用"
recurrence:
type: weeks
period: 1
week_days: ["Sat"]6.5 オンコール対応体制(将来検討)
注意: 現状はSlack通知までの実装。将来的なオンコール対応体制については、別途検討・設計が必要 https://fastdoctor.atlassian.net/browse/SRE-1763
今後の検討事項:
- オンコールツール導入
- 自動エスカレーションの仕組み構築
- オンコールローテーション体制の確立
- 24時間365日対応体制の検討
- Auto Scalingによるリアルタイム負荷対応
7. ダッシュボード設計(TBD)
モニタリング、アラートの設計・実装を優先するため、DatadogおよびCloudwatchのダッシュボードの設計については、必要となった場合に改めて検討する。
8. 実装例
TBD: 後でサンプル設定したディレクトリパスを指定します。
9. 運用ガイド
9.1 監視運用の開始
初期セットアップ
担当: 実装したオーナーチームのSRE
- アラート設定の実装
resource "aws_cloudwatch_metric_alarm" "alb_502" {
alarm_name = "${var.service_name}-prod-alb-502-critical"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
metric_name = "HTTPCode_ELB_5XX_Count"
namespace = "AWS/ApplicationELB"
period = 300 # 5分
statistic = "Sum"
threshold = 5
alarm_description = "ALB 502エラーが5分間で5回を超えました"
treat_missing_data = "notBreaching"
dimensions = {
LoadBalancer = aws_lb.main.arn_suffix
}
alarm_actions = [
aws_sns_topic.pager.arn
]
ok_actions = [
aws_sns_topic.pager.arn
]
tags = {
env = "prod"
service = var.service_name
team = var.team_name
severity = "critical"
component = "alb"
}
}Target 5xxエラー監視
resource "aws_cloudwatch_metric_alarm" "target_5xx" {
alarm_name = "${var.service_name}-prod-target-5xx-critical"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
# エラー率で判定
metric_query {
id = "error_rate"
expression = "(m1 / m2) * 100"
label = "Error Rate (%)"
return_data = true
}
metric_query {
id = "m1"
metric {
metric_name = "HTTPCode_Target_5XX_Count"
namespace = "AWS/ApplicationELB"
period = 300
stat = "Sum"
dimensions = {
TargetGroup = aws_lb_target_group.app.arn_suffix
LoadBalancer = aws_lb.main.arn_suffix
}
}
}
metric_query {
id = "m2"
metric {
metric_name = "RequestCount"
namespace = "AWS/ApplicationELB"
period = 300
stat = "Sum"
dimensions = {
TargetGroup = aws_lb_target_group.app.arn_suffix
LoadBalancer = aws_lb.main.arn_suffix
}
}
}
threshold = 1 # 1%
alarm_description = "Target 5xxエラー率が1%を超えました"
treat_missing_data = "notBreaching"
alarm_actions = [aws_sns_topic.pager.arn]
ok_actions = [aws_sns_topic.pager.arn]
tags = {
env = "prod"
service = var.service_name
team = var.team_name
severity = "critical"
component = "alb"
}
}ALB レイテンシ監視
resource "aws_cloudwatch_metric_alarm" "alb_latency" {
alarm_name = "${var.service_name}-prod-alb-latency-high"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
metric_name = "TargetResponseTime"
namespace = "AWS/ApplicationELB"
period = 300
extended_statistic = "p95"
threshold = 0.7 # 700ms
alarm_description = "ALB p95レイテンシが700msを超えました"
treat_missing_data = "notBreaching"
dimensions = {
LoadBalancer = aws_lb.main.arn_suffix
}
alarm_actions = [aws_sns_topic.notice.arn]
ok_actions = [aws_sns_topic.notice.arn]
tags = {
env = "prod"
service = var.service_name
team = var.team_name
severity = "high"
component = "alb"
}
}ECS Running < Desired監視
resource "aws_cloudwatch_metric_alarm" "ecs_task_shortage" {
alarm_name = "${var.service_name}-prod-ecs-task-shortage-critical"
comparison_operator = "LessThanThreshold"
evaluation_periods = 1
threshold = 0
alarm_description = "RunningタスクがDesiredより少ない状態が5分継続"
treat_missing_data = "breaching"
metric_query {
id = "shortage"
expression = "m1 - m2"
label = "Task Shortage"
return_data = true
}
metric_query {
id = "m1"
metric {
metric_name = "DesiredTaskCount"
namespace = "ECS/ContainerInsights"
period = 300
stat = "Average"
dimensions = {
ServiceName = var.service_name
ClusterName = var.cluster_name
}
}
}
metric_query {
id = "m2"
metric {
metric_name = "RunningTaskCount"
namespace = "ECS/ContainerInsights"
period = 300
stat = "Average"
dimensions = {
ServiceName = var.service_name
ClusterName = var.cluster_name
}
}
}
alarm_actions = [aws_sns_topic.pager.arn]
ok_actions = [aws_sns_topic.pager.arn]
tags = {
env = "prod"
service = var.service_name
team = var.team_name
severity = "critical"
component = "ecs"
}
}ECS CPU高負荷監視
resource "aws_cloudwatch_metric_alarm" "ecs_cpu_high" {
alarm_name = "${var.service_name}-prod-ecs-cpu-high"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
metric_name = "CPUUtilization"
namespace = "ECS/ContainerInsights"
period = 300
statistic = "Average"
threshold = 70
alarm_description = "ECS CPU使用率が70%を超えました"
treat_missing_data = "notBreaching"
dimensions = {
ServiceName = var.service_name
ClusterName = var.cluster_name
}
alarm_actions = [aws_sns_topic.notice.arn]
ok_actions = [aws_sns_topic.notice.arn]
tags = {
env = "prod"
service = var.service_name
team = var.team_name
severity = "high"
component = "ecs"
}
}RDS接続数監視
resource "aws_cloudwatch_metric_alarm" "rds_connections_high" {
alarm_name = "${var.db_identifier}-prod-connections-high"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2
metric_name = "DatabaseConnections"
namespace = "AWS/RDS"
period = 60
statistic = "Average"
threshold = var.max_connections * 0.8 # 最大の80%
alarm_description = "RDS接続数が最大の80%を超えました"
treat_missing_data = "notBreaching"
dimensions = {
DBInstanceIdentifier = var.db_identifier
}
alarm_actions = [aws_sns_topic.notice.arn]
ok_actions = [aws_sns_topic.notice.arn]
tags = {
env = "prod"
service = var.service_name
team = var.team_name
severity = "high"
component = "rds"
}
}Redis メモリ使用率監視
resource "aws_cloudwatch_metric_alarm" "redis_memory_high" {
alarm_name = "${var.cache_cluster_id}-prod-memory-critical"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2
metric_name = "DatabaseMemoryUsagePercentage"
namespace = "AWS/ElastiCache"
period = 60
statistic = "Average"
threshold = 80
alarm_description = "Redisメモリ使用率が80%を超えました"
treat_missing_data = "notBreaching"
dimensions = {
CacheClusterId = var.cache_cluster_id
}
alarm_actions = [aws_sns_topic.notice.arn]
ok_actions = [aws_sns_topic.notice.arn]
tags = {
env = "prod"
service = var.service_name
team = var.team_name
severity = "high"
component = "redis"
}
}8.2 EventBridge Rules
ECSイベント監視
resource "aws_cloudwatch_event_rule" "ecs_deployment_failed" {
name = "${var.service_name}-prod-ecs-deployment-failed"
description = "ECSデプロイ失敗を検知"
event_pattern = jsonencode({
source = ["aws.ecs"]
detail-type = ["ECS Service Action"]
detail = {
eventName = ["SERVICE_DEPLOYMENT_FAILED"]
clusterArn = [aws_ecs_cluster.main.arn]
}
})
tags = {
env = "prod"
service = var.service_name
team = var.team_name
}
}
resource "aws_cloudwatch_event_target" "ecs_deployment_failed_sns" {
rule = aws_cloudwatch_event_rule.ecs_deployment_failed.name
target_id = "SendToPager"
arn = aws_sns_topic.pager.arn
input_transformer {
input_paths = {
cluster = "$.detail.clusterArn"
service = "$.detail.eventName"
time = "$.time"
}
input_template = <<EOF
{
"alert": "ECSデプロイ失敗",
"severity": "critical",
"cluster": <cluster>,
"event": <service>,
"time": <time>
}
EOF
}
}
resource "aws_cloudwatch_event_rule" "ecs_task_stopped" {
name = "${var.service_name}-prod-ecs-task-stopped"
description = "ECSタスク異常停止を検知"
event_pattern = jsonencode({
source = ["aws.ecs"]
detail-type = ["ECS Task State Change"]
detail = {
lastStatus = ["STOPPED"]
stoppedReason = [{
"exists": true
}]
clusterArn = [aws_ecs_cluster.main.arn]
}
})
}
resource "aws_cloudwatch_event_target" "ecs_task_stopped_lambda" {
rule = aws_cloudwatch_event_rule.ecs_task_stopped.name
target_id = "AnalyzeStopReason"
arn = aws_lambda_function.task_stop_analyzer.arn
}RDSイベント監視
resource "aws_cloudwatch_event_rule" "rds_instance_events" {
name = "${var.service_name}-prod-rds-critical-events"
description = "RDS重大イベントを検知"
event_pattern = jsonencode({
source = ["aws.rds"]
detail-type = ["RDS DB Instance Event"]
detail = {
EventCategories = ["failover", "failure", "notification"]
}
})
}
resource "aws_cloudwatch_event_target" "rds_events_sns" {
rule = aws_cloudwatch_event_rule.rds_instance_events.name
target_id = "SendToPager"
arn = aws_sns_topic.pager.arn
}8.3 SNS Topics
SNS Topics設定
# Pager用 (Critical)
resource "aws_sns_topic" "pager" {
name = "${var.service_name}-prod-alerts-critical"
tags = {
env = "prod"
service = var.service_name
team = var.team_name
severity = "critical"
}
}
# 将来的にPagerDutyなどのオンコールツールを導入する場合は以下のような設定を追加
# resource "aws_sns_topic_subscription" "pagerduty" {
# topic_arn = aws_sns_topic.pager.arn
# protocol = "https"
# endpoint = var.pagerduty_endpoint
# }
# 通知用 (High/Medium)
resource "aws_sns_topic" "notice" {
name = "${var.service_name}-prod-alerts-high"
tags = {
env = "prod"
service = var.service_name
team = var.team_name
severity = "high"
}
}
resource "aws_sns_topic_subscription" "slack" {
topic_arn = aws_sns_topic.notice.arn
protocol = "lambda"
endpoint = aws_lambda_function.slack_notifier.arn
}8.4 Datadog Monitors (Terraform)
Datadog Provider設定
terraform {
required_providers {
datadog = {
source = "DataDog/datadog"
version = "~> 3.0"
}
}
}
provider "datadog" {
api_key = var.datadog_api_key
app_key = var.datadog_app_key
api_url = "https://api.datadoghq.com"
}ALB 502監視
resource "datadog_monitor" "alb_502" {
name = "prod/${var.service_name}: ALB 502 Error Spike"
type = "query alert"
message = <<EOF
ALB 502エラーが急増しています。
**影響範囲**: ユーザーアクセス不可
**想定原因**:
- バックエンドタスクの全停止
- ヘルスチェック失敗
- タイムアウト設定の問題
**対応手順**:
1. ECSタスクの状態確認: `aws ecs describe-services`
2. ヘルスチェックログ確認
3. Runbook参照: https://wiki.example.com/runbook/alb-502
@slack-#notifications_server_prod
EOF
query = "sum(last_5m):sum:aws.applicationelb.httpcode_elb_5xx_count{env:prod,service:${var.service_name},*} > 10"
monitor_thresholds {
critical = 10
warning = 5
}
notify_no_data = false
renotify_interval = 60
timeout_h = 0
include_tags = true
require_full_window = false
tags = [
"env:prod",
"service:${var.service_name}",
"team:${var.team_name}",
"component:alb",
"severity:critical"
]
}Target 5xx監視
resource "datadog_monitor" "target_5xx_rate" {
name = "prod/${var.service_name}: Target 5xx Error Rate > 1%"
type = "query alert"
message = <<EOF
アプリケーション5xxエラー率が1%を超えています。
**影響**: サービス品質低下
**確認項目**:
- APMトレースで遅いエンドポイント特定
- アプリケーションログのエラー確認
- RDS/Redisの状態確認
**Runbook**: https://wiki.example.com/runbook/app-5xx
@slack-#notifications_server_prod
EOF
query = "sum(last_5m):sum:aws.applicationelb.httpcode_target_5xx_count{env:prod,service:${var.service_name}} / sum:aws.applicationelb.request_count{env:prod,service:${var.service_name}} * 100 > 1"
monitor_thresholds {
critical = 1.0
warning = 0.5
}
notify_no_data = false
renotify_interval = 60
tags = [
"env:prod",
"service:${var.service_name}",
"team:${var.team_name}",
"component:app",
"severity:critical"
]
}ECS CPU監視
resource "datadog_monitor" "ecs_cpu_high" {
name = "prod/${var.service_name}: ECS CPU High (> 70%)"
type = "query alert"
message = <<EOF
ECS CPU使用率が高くなっています。
**影響**: パフォーマンス低下の可能性
**対応**:
1. Auto Scalingの動作確認
2. CPU使用率の高いプロセス特定
3. 必要に応じて手動スケールアウト
@slack-#notifications_server_prod
EOF
query = "avg(last_5m):avg:ecs.fargate.cpuutilization{env:prod,service:${var.service_name}} > 70"
monitor_thresholds {
critical = 70
warning = 60
}
notify_no_data = false
tags = [
"env:prod",
"service:${var.service_name}",
"team:${var.team_name}",
"component:ecs",
"severity:high"
]
}9. 運用ガイド
9.1 監視運用の開始
初期セットアップ
アラート設定の実装
- 本ドキュメントの閾値を初期値として設定
- Slack通知先:
#notifications_server_prod - タグ付け:
env,service,teamを必須設定
観察期間の確保
- 最初の1週間: アラート発生状況の記録
- 誤検知/見逃しの洗い出し
- ベースライン値の把握
段階的な調整
- 2週目以降: 閾値・評価期間の最適化
- 月次: 定期レビューと設定見直し
9.2 インシデント対応フロー (基本)
注意: 詳細なエスカレーションマトリクス、対応手順(Runbook)、コミュニケーションガイドラインについては、別途検討・整備を行います。
10. 参考資料
- AWS Well-Architected Framework - Operational Excellence Pillar
- Datadog Best Practices
- ECS Best Practices Guide
- ALB Access Logs
- Amazon ECS イベント
- Amazon RDS イベント通知の操作
11. 変更履歴
| 日付 | バージョン | 変更内容 | 担当者 |
|---|---|---|---|
| 2025-10-22 | 1.0 | 初版作成 | - |