AWS Chatbot + Terraform で実装する CloudWatch エラーログの Slack 通知

📌 はじめに

実装の背景と目的

とあるアプリケーションがサーバー上で稼働していましたが、これまでアラートの設定が行われていませんでした。今回、エラーをリアルタイムに検知し、チームが即座に対応できる体制を構築するため、AWS CloudWatch Logs と Slack を連携した通知システムを Terraform で実装しました。
設定パラメータの意味や、ハマりどころをまとめました。

AWS Chatbot を使うメリット

📝 注記: AWS Chatbot は 2025 年 2 月 19 日に Amazon Q Developer に変更されました。マネージメントコンソール上は、Amazon Q Developer in chat applications となっています。本記事では従来の名称「AWS Chatbot」を使用しますが、機能は同じです。字面の関係上、名称が長いので Chatbot でいかせてもらいます。

従来は Lambda を使った通知が一般的でしたが、AWS Chatbot を使うことで以下のメリットがあります:

項目 Lambda パターン AWS Chatbot パターン
コード管理 Lambda 関数のコード管理・デプロイが必要 不要 – 設定のみで完結
メンテナンス ランタイムバージョン管理、依存関係更新 AWS が管理 – 自動更新
実装難易度 Slack API の実装、エラーハンドリング 簡単 – 宣言的設定のみ
コスト Lambda 実行料金 無料 – Chatbot 自体は無料
信頼性 自前実装の品質に依存 AWS が保証 – マネージドサービス
インタラクティブ対応 カスタム実装が必要 組み込み – ボタン操作対応

結論: 通知目的だけなら、AWS Chatbot の方が圧倒的に効率的です。

アーキテクチャ構成の理解

AWS Chatbot を使った通知の仕組みは、AWS のサービス連携により CloudWatch Logs → Metric Filter → Alarm → SNS → Chatbot → Slack という流れになります。特に、Chatbot は SNS 経由でしか動作しないという AWS の制約があるため、必然的にこの構成となります。

なぜ SNS 経由なのか?

Amazon Q Developer in chat applications (旧 AWS Chatbot) は、SNS Topic 経由でのみ通知を受け取るという仕組みになっています。

AWS の制約:

  • ❌ CloudWatch Alarm → Slack への直接通知は不可能
  • ✅ CloudWatch Alarm → SNS → Amazon Q Developer → Slack という経路が必須

この制約は AWS のアーキテクチャ設計によるもので、すべての AWS サービスが SNS を中心としたイベント駆動型の統合を採用しているためです。

参考: 公式ドキュメント – Monitoring AWS services
“All services that work with Amazon Q Developer in chat applications use Amazon SNS topics as targets to send event and alarm notifications.”


📋 前提条件

本記事で紹介する実装は、以下の環境を前提としています。

必須環境・ツール

項目 バージョン 備考
Terraform >= 0.14.0 本実装では 1.x 系を推奨
AWS Provider ~> 5.61.0 AWS Chatbot リソース対応バージョン
AWS アカウント CloudWatch、SNS、Chatbot の操作権限が必要
Slack ワークスペース チャンネル作成・管理権限が必要

環境

1. CloudWatch Logs へのログ出力

アプリケーションから CloudWatch Logs にログが出力されている状態です。

本実装では以下の構成を前提としています:

  • ログ出力元: ECS Fargate (API/Batch コンテナ)
  • Log Group 名: /ecs/api, /ecs/batch
  • ログドライバー: awslogs (ECS Task Definition で設定)

2. ログフォーマット: JSON 形式

エラー検知のため、ログは JSON 形式level_name フィールドを含む必要があります。

本リポジトリの実際のログ例:

{
  "level_name": "ERROR",
  "message": "request_error",
  "context": {
    "status": 500,
    "exception": {
      "class": "RuntimeException",
      "message": "Database connection failed",
      "trace": "..."
    }
  },
  "datetime": "2025-10-21T03:07:31.263879+00:00"
}

CloudWatch Log Metric Filter のパターン:

{ $.level_name = "ERROR" }

JSON ログから level_name"ERROR" のログを抽出します。

必要な権限

AWS 側の権限

本実装を実行するユーザー/ロールには、以下のサービスの権限が必要です:

  • CloudWatch Logs: Log Group の読み取り、Log Metric Filter の作成
  • CloudWatch Alarms: Alarm の作成・管理
  • SNS: Topic の作成、ポリシーの設定
  • AWS Chatbot: Chatbot Configuration の作成、IAM Role の管理
  • IAM: Chatbot 用 Role の作成

Slack 側の権限

  • ワークスペース管理者権限: OAuth 認証のため
  • チャンネル作成権限: 通知先チャンネルの準備

🏗️ システムアーキテクチャとデータフロー

アーキテクチャ全体像

通知システムは以下のコンポーネントで構成され、CloudWatch Logs → Metric Filter → Alarm → SNS → Chatbot → Slack という流れでエラーを検知・通知します。

各コンポーネントの役割

コンポーネント 責務 主な機能 設定のポイント
CloudWatch Logs ログ収集 アプリケーションからの JSON ログを受信・保存 Log Group 名、保持期間の設定
Log Metric Filter ログ解析 JSON パターンマッチングでエラーログを抽出 { $.level_name = "ERROR" } パターン
CloudWatch Metric メトリクス集計 エラー数を時系列データとして集計 Namespace、メトリクス名の設計
CloudWatch Alarm 閾値監視 メトリクスが閾値を超えたらアラートを発火 閾値、評価期間、統計方法の選択
SNS Topic メッセージング アラーム通知を受信し、サブスクライバーに配信 アクセス権限ポリシーの設定
AWS Chatbot 通知変換 SNS メッセージを Slack フォーマットに変換 Slack 認証、IAM Role の設定
Slack Channel 可視化 チームメンバーにリアルタイムで通知 チャネル ID、ワークスペース ID の取得

エラー発生から通知までの流れ

エラー発生から Slack 通知までの詳細なシーケンス:

  1. エラー発生 (Application Layer)

    • API/Batch で例外が発生し、JSON 形式でログ出力
    • 例: {"level_name": "ERROR", "message": "request_error", "context": {...}}
  2. ログ収集 (CloudWatch Logs) – 1 秒以内

    • ECS Fargate から CloudWatch Logs /ecs/api または /ecs/batch にログが送信される
  3. パターンマッチング (Log Metric Filter) – リアルタイム

    • { $.level_name = "ERROR" } でエラーログを抽出
    • マッチしたログ 1 件につき、メトリクス値を 1 増加
  4. メトリクス集計 (CloudWatch Metric) – 60 秒間

    • 60 秒間のエラーログ件数を合計 (Sum)
    • APIErrorCount または BatchErrorCount メトリクスとして記録
  5. 閾値評価 (CloudWatch Alarm) – 60 秒ごと

    • Sum >= 3 (デフォルト閾値) かチェック
    • 閾値を超えた場合、ALARM 状態に遷移
  6. 通知発行 (SNS Topic)

    • CloudWatch Alarm から SNS Topic にメッセージ発行
    • サブスクライバー(Chatbot)にメッセージ配信
  7. Slack 形式変換 (AWS Chatbot)

    • SNS メッセージを Slack フォーマットに変換
    • アラーム詳細やインタラクティブボタンを追加
  8. 通知表示 (Slack) – 合計 1-2 分

    • #alerts チャネルにメッセージを投稿
    • 担当者に即時通知

復旧フロー: エラー数が閾値を下回ると、OK 状態に遷移し、復旧通知が送信されます(ok_actions が設定されている場合)


🛠️ Terraform 実装の詳細解説

データの流れに沿って、各コンポーネントの Terraform 実装例を解説します。

a) Log Metric Filter (aws_cloudwatch_log_metric_filter)

目的: CloudWatch Logs から ERROR レベルのログを抽出し、メトリクスに変換

resource "aws_cloudwatch_log_metric_filter" "api_errors" {
  name           = "${var.name_prefix}-api-errors"
  log_group_name = var.api_log_group_name
  pattern        = "{ $.level_name = \"ERROR\" }"

  metric_transformation {
    name      = "APIErrorCount"
    namespace = "${var.name_prefix}/Logs"
    value     = "1"
    unit      = "Count"
  }
}

JSON パターンマッチングの詳細

Log Metric Filter は CloudWatch Logs から特定のパターンに一致するログを抽出し、メトリクスに変換します。

パターン { $.level_name = \"ERROR\" } は、JSON ログの level_name フィールドが "ERROR" と完全一致するログを抽出します。$ は JSON のルート要素を表し、\" は Terraform 内でダブルクォートをエスケープするための記法です。

実際のログ例とマッチング

{
  "level_name": "ERROR",
  "message": "request_error",
  "context": {
    "status": 500,
    "exception": {
      "class": "RuntimeException",
      "message": "Database connection failed"
    }
  },
  "datetime": "2025-10-21T03:07:31.263879+00:00"
}


{
  "level_name": "ERROR",
  "message": "job_error",
  "context": {
    "job": "sample_batch_job",
    "exception": {
      "class": "ApiException",
      "message": "API rate limit exceeded"
    }
  },
  "datetime": "2025-10-21T03:05:37.791542+00:00"
}


{
  "level_name": "WARNING",
  "message": "slow_query",
  "context": {
    "query_time": 2.5
  },
  "datetime": "2025-10-21T03:08:15.123456+00:00"
}

{
  "level_name": "WARNING",
  "message": "ERROR",
  "context": {
    "query_time": 2.5
  },
  "datetime": "2025-10-21T03:08:15.123456+00:00"
}

その他のパターン例:

# 厳密一致
{ $.level_name = "ERROR" }

# OR 条件
{ $.level_name = "ERROR" || $.level_name = "CRITICAL" }

# ワイルドカード
{ $.message = "database*" }

参考: より詳細なパターン構文については、公式ドキュメント – Filter pattern syntax を参照してください。

metric_transformation の設計

パラメータ 設定値 意味と選定理由
name "APIErrorCount" アラームで参照するメトリクスの識別子。
namespace "${var.name_prefix}/Logs" カスタムメトリクスの名前空間
value "1" カウント方式: マッチしたログ 1 件につきメトリクス値を 1 増加。Sum 統計で集計することでエラー総数を取得
unit "Count" 単位の明示: メトリクスの単位を明示的に指定。CloudWatch Console での表示や、他のメトリクスとの比較に使用

b) CloudWatch Alarm (aws_cloudwatch_metric_alarm)

目的: メトリクスが閾値を超えた際に SNS Topic に通知を送信

resource "aws_cloudwatch_metric_alarm" "api_errors" {
  alarm_name          = "${var.name_prefix}-api-high-error-rate"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = var.evaluation_periods
  metric_name         = "APIErrorCount"
  namespace           = "${var.name_prefix}/Logs"
  period              = var.period_seconds
  statistic           = "Sum"
  threshold           = var.error_threshold
  alarm_description   = "API error count exceeded ${var.error_threshold} in ${var.period_seconds} seconds"
  alarm_actions       = [aws_sns_topic.alerts.arn]
  ok_actions          = var.notify_on_ok ? [aws_sns_topic.alerts.arn] : []
  treat_missing_data  = "notBreaching"

  tags = {
    Name        = "${var.name_prefix}-api-high-error-rate"
    Environment = var.env
    Component   = "API"
  }
}

パラメータの解説

パラメータ 説明 設定値
alarm_name アラームの識別名。CloudWatch Console やログで表示される名前 "${var.name_prefix}-api-high-error-rate"
comparison_operator メトリクス値と閾値を比較する演算子 "GreaterThanOrEqualToThreshold" (以上)
evaluation_periods 何回連続で閾値を超えたらアラームを発火するか 1 (即座に通知)
metric_name 監視対象のメトリクス名。Log Metric Filter で作成したメトリクスを参照 "APIErrorCount"
namespace メトリクスが属する名前空間。カスタムメトリクスは任意の名前空間を指定可能 "${var.name_prefix}/Logs"
period メトリクスの評価期間(秒)。この期間内でメトリクス値を集計 60 (1 分間)
statistic メトリクスの集計方法 "Sum" (合計値)
threshold アラームをトリガーする閾値 3 (3 個以上のエラー)
alarm_description アラームの説明文。Slack 通知にも表示される "API error count exceeded 3 in 60 seconds"
alarm_actions ALARM 状態に遷移した時に実行するアクション(SNS Topic ARN) [aws_sns_topic.alerts.arn]
ok_actions OK 状態に復帰した時に実行するアクション [aws_sns_topic.alerts.arn] または [] (復旧通知の有無)
treat_missing_data データが来ない場合の扱い。notBreaching = データ欠損時はアラームを発火しない(正常扱い) "notBreaching"

閾値設計の考え方

CloudWatch Alarm は以下の条件で評価されます:

評価式: Sum(APIErrorCount) >= 3 errors in 60 seconds for 1 period

評価プロセス:

  1. 60 秒間にエラーログが 4 件発生
  2. Log Metric Filter が各ログをカウント(1 件 = 値 1)
  3. CloudWatch Metric が 60 秒間の合計を計算: Sum = 4
  4. CloudWatch Alarm が閾値と比較: 4 >= 3ALARM 状態へ遷移
  5. SNS Topic にメッセージを発行 → Slack 通知

エラー数が閾値を下回ると(Sum < 3)、OK 状態に戻ります。

パラメータの関係性

パラメータ デフォルト値 意味
threshold 3 閾値: この値以上でアラート
period 60 (秒) 評価期間: この期間内でのメトリクス集計
evaluation_periods 1 連続期間: 何回連続で閾値超過したらアラート
statistic "Sum" 集計方法: メトリクスの計算方法
comparison_operator "GreaterThanOrEqualToThreshold" 比較演算子: 閾値との比較方法

alarm_actions と ok_actions の違い

パラメータ トリガー 用途
alarm_actions OKALARM 遷移時 問題発生通知: エラーが閾値を超えたときに Slack 通知
ok_actions ALARMOK 遷移時 復旧通知: エラーが閾値を下回り、正常に戻ったときに Slack 通知
insufficient_data_actions データ不足時 データ欠損通知: Log Group が存在しない、データが来ないなどの異常検知

CloudWatch Alarm の 3 つの状態:

  1. OK 状態 (初期状態)

    • エラー数が閾値未満
    • ok_actions 実行: 復旧通知を Slack に送信(設定により有効化)
    • Slack メッセージ例: ✅ 復旧しました
  2. ALARM 状態

    • エラー数が閾値以上(Sum >= 3
    • alarm_actions 実行: 問題発生通知を Slack に送信
    • Slack メッセージ例: 🚨 API でエラー急増!
  3. INSUFFICIENT_DATA 状態

    • Log Group が存在しない、またはデータが来ない
    • insufficient_data_actions 実行可能(今回は未設定)
    • データ復旧後、自動的に OK 状態に戻る

状態遷移:

  • OK → ALARM: エラー数が閾値を超えた時
  • ALARM → OK: エラー数が閾値を下回った時
  • OK/ALARM → INSUFFICIENT_DATA: ログデータが途絶えた時
  • INSUFFICIENT_DATA → OK: ログデータが復旧した時

treat_missing_data の選択理由

設定値 動作 選択理由
"notBreaching" データがない = 正常 この実装で選択: ログがない = エラーがない = 正常。深夜帯など API アクセスがない時間帯でも誤アラートを防止
"breaching" データがない = 異常 アプリケーションが動作しているはずなのにログがない場合に使用。監視の監視が必要
"ignore" データがない = 評価しない evaluation_periods が複数の場合に使用。今回は 1 なので不適切
"missing" データがない = INSUFFICIENT_DATA 状態 通知がうるさくなるため、今回は不要

c) SNS Topic (aws_sns_topic)

目的: CloudWatch Alarm からの通知を受け取り、AWS Chatbot に配信するメッセージハブ

resource "aws_sns_topic" "alerts" {
  name         = "${var.name_prefix}-alerts"
  display_name = "CloudWatch Alerts for ${var.env}"

  tags = {
    Name        = "${var.name_prefix}-alerts"
    Environment = var.env
  }
}

パラメータの詳細解説

パラメータ 設定値 目的・理由
name ${var.name_prefix}-alerts SNS Topic の識別名
display_name CloudWatch Alerts for ${var.env} AWS Console や Slack 通知で表示される名前。環境を示す情報を含めておくとわかりやすい。
tags Name, Environment コスト配分タグ、リソース識別、自動化スクリプトでの検索を可能にする

d) SNS Topic Policy (aws_sns_topic_policy)

目的: CloudWatch Alarm が SNS Topic に Publish できるようにするアクセス許可ポリシー

resource "aws_sns_topic_policy" "alerts" {
  arn = aws_sns_topic.alerts.arn

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid    = "AllowCloudWatchAlarmsPublish"
        Effect = "Allow"
        Principal = {
          Service = "cloudwatch.amazonaws.com"
        }
        Action   = "SNS:Publish"
        Resource = aws_sns_topic.alerts.arn
      },
      {
        Sid    = "AllowChatbotSubscribe"
        Effect = "Allow"
        Principal = {
          Service = "chatbot.amazonaws.com"
        }
        Action = [
          "SNS:Subscribe",
        ]
        Resource = aws_sns_topic.alerts.arn
      }
    ]
  })
}

Policy 内容の詳細

2 つの Statement で権限を分離:

Statement ID Principal (誰が) Action (何を) 目的
AllowCloudWatchAlarmsPublish CloudWatch サービス SNS:Publish アラーム発生時にメッセージを送信
AllowChatbotSubscribe Chatbot サービス SNS:Subscribe SNS Topic をサブスクライブ

e) IAM Role for Chatbot (aws_iam_role)

目的: AWS Chatbot が CloudWatch のメトリクスやログ情報を取得するための権限付与

resource "aws_iam_role" "chatbot" {
  name = "${var.name_prefix}-chatbot-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = {
          Service = "chatbot.amazonaws.com"
        }
        Action = "sts:AssumeRole"
      }
    ]
  })

  managed_policy_arns = [
    "arn:aws:iam::aws:policy/CloudWatchReadOnlyAccess"
  ]

  tags = {
    Name        = "${var.name_prefix}-chatbot-role"
    Environment = var.env
  }
}

resource "aws_iam_role_policy" "chatbot" {
  name = "${var.name_prefix}-chatbot-policy"
  role = aws_iam_role.chatbot.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = [
          "cloudwatch:Describe*",
          "cloudwatch:Get*",
          "cloudwatch:List*"
        ]
        Resource = "*"
      },
      {
        Effect = "Allow"
        Action = [
          "logs:DescribeLogGroups",
          "logs:DescribeLogStreams",
          "logs:GetLogEvents",
          "logs:FilterLogEvents"
        ]
        Resource = [
          "arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:log-group:${var.api_log_group_name}:*",
          "arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:log-group:${var.batch_log_group_name}:*"
        ]
      }
    ]
  })
}

f) AWS Chatbot Configuration (aws_chatbot_slack_channel_configuration)

目的: SNS からの通知を Slack チャネルに転送する設定

resource "aws_chatbot_slack_channel_configuration" "alerts" {
  configuration_name = "${var.name_prefix}-slack-alerts"
  iam_role_arn       = aws_iam_role.chatbot.arn
  slack_channel_id   = var.slack_channel_id
  slack_team_id      = var.slack_workspace_id

  sns_topic_arns = [
    aws_sns_topic.alerts.arn
  ]

  logging_level = "INFO"

  tags = {
    Name        = "${var.name_prefix}-slack-alerts"
    Environment = var.env
  }
}

各パラメータの意味

パラメータ 説明 設定例 バリデーション
configuration_name Chatbot 設定の識別子 myapp-dev-slack-alerts 英数字とハイフン
iam_role_arn Chatbot が使用する IAM Role 上記で作成した Role の ARN ARN 形式
slack_channel_id 通知先 Slack チャネル ID C0123456789 C で始まる英数字
slack_team_id Slack ワークスペース ID T0123456789 T で始まる英数字
sns_topic_arns 購読する SNS Topic のリスト [aws_sns_topic.alerts.arn] ARN のリスト
logging_level Chatbot のログレベル INFO ERROR / INFO / NONE

📦 Terraform モジュール構成

モジュールの依存関係

Monitoring モジュールが作成するリソース:

  1. SNS Topic (aws_sns_topic)

    • CloudWatch Alarm からの通知を受信
  2. SNS Topic Policy (aws_sns_topic_policy)

    • CloudWatch と Chatbot に SNS Topic へのアクセス権限を付与
  3. Log Metric Filter (aws_cloudwatch_log_metric_filter) × 2

    • API とバッチのエラーログを抽出してメトリクス化
  4. CloudWatch Alarm (aws_cloudwatch_metric_alarm) × 2

    • API とバッチのエラーメトリクスを監視
  5. IAM Role (aws_iam_role)

    • Chatbot が CloudWatch にアクセスするための権限
  6. IAM Role Policy (aws_iam_role_policy)

    • Chatbot 用の最小権限ポリシー
  7. Chatbot Configuration (aws_chatbot_slack_channel_configuration)

リソース間の参照関係:

  • CloudWatch Alarm → SNS Topic (通知先)
  • Chatbot Configuration → SNS Topic (サブスクリプション)
  • Chatbot Configuration → IAM Role (権限)
  • Log Metric Filter → CloudWatch Alarm (メトリクス名)

variables.tf の設計思想

variable "name_prefix" {
  type        = string
  description = "Prefix for resource names"
}

variable "env" {
  type        = string
  description = "Environment name (dev/prd)"
}

variable "api_log_group_name" {
  type        = string
  description = "CloudWatch Log Group name for API"
}

variable "batch_log_group_name" {
  type        = string
  description = "CloudWatch Log Group name for Batch"
}

variable "error_threshold" {
  type        = number
  description = "Error count threshold for alarms"
  default     = 3
}

variable "evaluation_periods" {
  type        = number
  description = "Number of periods to evaluate"
  default     = 1
}

variable "period_seconds" {
  type        = number
  description = "Period in seconds for metric evaluation"
  default     = 60
}

variable "slack_workspace_id" {
  type        = string
  description = "Slack Workspace ID (Team ID) for AWS Chatbot integration"
  sensitive   = true

  validation {
    condition     = can(regex("^T[A-Z0-9]{8,}$", var.slack_workspace_id))
    error_message = "Slack Workspace ID must start with 'T' followed by at least 8 alphanumeric characters"
  }
}

variable "slack_channel_id" {
  type        = string
  description = "Slack Channel ID for notifications"
  sensitive   = true

  validation {
    condition     = can(regex("^C[A-Z0-9]{8,}$", var.slack_channel_id))
    error_message = "Slack Channel ID must start with 'C' followed by at least 8 alphanumeric characters"
  }
}

variable "notify_on_ok" {
  type        = bool
  description = "Send Slack notifications when alarms return to OK state"
  default     = true
}
  • slack_team_id、slack_channel_id についてはsensitive = trueでマスキング
    設定値は Terraform Cloud の変数に登録し、apply 時に設定される様にしています。

🚀 実装手順

1. AWS Chatbot の事前準備(必須)

重要: Terraform apply の前に、AWS Console で Slack OAuth 認証を完了する必要があります。

やり忘れると、Terraform apply で Chatbot へ Slack チャンネルの登録で失敗します。
失敗しても認証完了後に再度 apply を実行すれば成功します。

認証手順

  • Chatbot のページを開き、右側の「チャットクライアントの選択」で Slack を選択し、その下の「クライアントを設定」ボタンクリック

  • Slack のワークスペースに「Amazon Q Developer」のインストールを要求されるので許可

2. Terraform 変数の設定

terraform.tfvars の作成


name_prefix = "myapp-dev"
env         = "dev"


api_log_group_name   = "/ecs/api"
batch_log_group_name = "/ecs/batch"


error_threshold    = 3
evaluation_periods = 1
period_seconds     = 60





notify_on_ok = true

3. Terraform Apply

Dev 環境での検証


terraform init -upgrade


terraform plan

















terraform apply

4. 動作確認方法

Step 0: 事前準備 – Slack チャンネルへAmazonQの招待

AWS Chatbot が Slack チャンネルにメッセージを投稿するためには、対象のチャンネルに Amazon Q Developer を招待する必要があります。

Slack の対象チャンネルで以下のコマンドを実行してください。

Step 1: アラームを生成

  • メトリクスを選択
    Terraformで作成されたメトリクス APIErrorCount を選択します。Slackに通知が届くことを確認できれば良いので何を選んでも良いです。
  • 期間を「10秒」に変更
  • 条件:しきい値は静的、アラームの条件は「より低い」、しきい値は「1」
  • その他の設定で欠損データの処理を「欠落データを不正 (しきい値を超えている)として処理」を選択

  • 通知設定で、先ほど作成した SNS トピックを選択し、アラームを作成します。

Step 2: Slack 通知の確認

この状態で10秒ちょっと待つとアラート状態になり、SNSトピック、Chatbotを経由し、Slack に通知が届きます。

🚨 CloudWatch Alarm | {作成したアラーム名} | ap-northeast-1 | Account: {アカウントID}
Threshold Crossed: no datapoints were received for 1 period and 1 missing datapoint was treated as [Breaching].

Namespace
sentinel-dev/Logs
Metric
BatchErrorCount
Timestamp
Tue, 28 Oct 2025 06:29:47 UTC
Alarm State
ALARM

Step 3: アラームの復旧確認

先ほど作成したアラームの条件を以下のように変更し、OK 状態に復帰させます。

  • その他の設定:欠損データの処理を「欠落データを適正 (しきい値を超えていない)として処理」を選択し、アラームを保存

アラームがOKに変わり、復旧通知が届きます。

✅ CloudWatch Alarm | {作成したアラーム名} | ap-northeast-1 | Account: {アカウントID}
Threshold Crossed: no datapoints were received for 1 period and 1 missing datapoint was treated as [NonBreaching].

Namespace
myapp/Logs
Metric
hErrorCount
Timestamp
Tue, 28 Oct 2025 06:56:36 UTC
Alarm State
OK

⚠️ ハマりポイントと解決策

1. AWS Provider バージョン問題

問題

Error: Invalid resource type
│
│   on main.tf line 67, in resource "aws_chatbot_slack_channel_configuration" "alerts":
│   67: resource "aws_chatbot_slack_channel_configuration" "alerts" {
│
│ The provider hashicorp/aws does not support resource type "aws_chatbot_slack_channel_configuration".

原因

aws_chatbot_slack_channel_configurationAWS Provider v5.61.0 で追加されました。
プロバイダーのバージョンが古いと認識されません。

解決策


terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.61.0"  
    }
  }
}

2. SNS トピックのポリシー設定不足

問題

SNSトピックのポリシーを厳しくしすぎて、CloudWatch Alarm や Chatbot がアクセスできない場合があります。
Terraform自体は成功するものの、Slack に通知が届かない。

解決策

SNSトピックポリシーに以下の2つのStatementが含まれていることを確認してください。

  1. CloudWatch Alarm が SNS トピックに Publish できる権限
  2. Chatbot が SNS トピックを Subscribe できる権限

3. Chatobot側のSlack 認証忘れ

問題

Slack 認証前に terraform apply すると以下のエラー:

Error: error creating Chatbot Slack Channel Configuration: InvalidParameterException:
Slack workspace T0123456789 is not authorized

原因

Terraform は Slack OAuth 認証を自動化できません。手動での認証が必須です。

解決策

必須の事前作業: Terraform Apply 前に AWS Console から Slack 認証が必要です。

手順:

  1. AWS Chatbot Console を開く
  2. “Configure a chat client” → “Slack” → “Configure client”
  3. Slack 認証画面で “許可する”
  4. 認証完了後、Terraform apply

4. Slack チャンネルへの Amazon Q 招待忘れ

問題

SlackワークスペースにAmazon Q Developerをインストールしただけでは、通知が届きません。
AWS Chatbot が Slack チャンネルにメッセージを投稿するためには、対象のチャンネルに Amazon Q Developer を招待する必要があります。

Slack の対象チャンネルで以下のコマンドを実行してください。

5. JSON パターンマッチングのデバッグ

問題

Log Metric Filter が期待通りにマッチしない:

pattern = "{ $.level_name = ERROR }"  

原因

JSON 文字列にはエスケープが必要です。

解決策

pattern = "{ $.level_name = \"ERROR\" }"  

デバッグ方法

AWS CLI でパターンをテスト

aws logs filter-log-events \
  --log-group-name /ecs/api \
  --filter-pattern '{ $.level_name = "ERROR" }' \
  --limit 5

期待される出力:

{
    "events": [
        {
            "logStreamName": "ecs/api/container-1",
            "timestamp": 1729568851263,
            "message": "{\"level_name\":\"ERROR\",\"message\":\"test_error\"}",
            "ingestionTime": 1729568851500,
            "eventId": "12345678901234567890"
        }
    ],
    "searchedLogStreams": [...]
}

マッチしない場合のチェックリスト:

確認項目 確認方法
ログが JSON 形式か aws logs get-log-events で実際のログを確認
フィールド名が一致するか level_name vs levelName の違いに注意
値が厳密一致するか ERROR vs Error の大文字小文字
エスケープが正しいか \"ERROR\" とダブルクォートをエスケープ


🎓 まとめ

本記事では、AWS Chatbot と Terraform を活用して、CloudWatch Logs のエラーログを Slack に通知する監視基盤を構築する方法を解説しました。
権限絞りすぎて通知が届かない、Chatbot の Slack 認証忘れなど、ハマりポイントも多いですが、一つ一つ丁寧に対処すれば確実に構築できます。

📚 参考資料


Source link

関連記事

コメント

この記事へのコメントはありません。