public memo

エンジニア向け小ネタ書き溜め用。公開日記だけど親切な文章とは程遠いかもしれない。

Lambdaの実行時エラーをChatbotでSlackに通知するのが便利すぎる話

2020-05-01 by MasakiMisawa
Tweet
このエントリーをはてなブックマークに追加
Pocket
LINEで送る

先日一般公開されたAWS Chatbotについて、beta版から使い続けてみた感想として ここがとても便利だった!という内容のお話です。
Terraformがまだ未対応だったり、対応サービスがまだ限定的(サブスクリプションに設定してSNSにpublishすれば何でも動く訳ではなく、対応サービスからpublishされた時のみ動作する)だったりなど、広がるのはもう少し先になりそうですが、今後爆発的に使われていくサービスなのは間違いなく、今回はその中でも特に便利だと感じたLambdaの実行時エラーをSlackに通知する時の内容を書いてみます。

AWS Chatbotとは?

AWSの公式ページでご確認下さいで詳細は省略しますが、ざっくり書くとSlack or Amazon Chimeのチャットに対してAWSリソースの各種イベントを通知したり、通知内容に対してチャット側で色々な操作(サポートケースを作成したり、Lambdaを呼び出したりなど)ができるインタラクティブエージェントサービスです。

今回は何をやるの?

使い方の説明と特に便利だと感じた内容の紹介を兼ねて、Lambdaの実行時エラーをCloudWatchAlarmで拾い、通知先のSNSのサブスクリプションにChatbotを設定してSlackに通知を飛ばすまでの一連の流れを一からやってみます。

必要なリソースの作成

という事で、早速作っていきます。

1. Lambdaの作成

まずは通知対象のLambdaを作成します。
実行した際に必ずエラーを起こしてくれれば良いので、今回は以下のようなexample_lambdaという関数を作成しました。

example_lambda
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
import logging
 
def lambda_handler(event, context):
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    
    logger.info('example lambda start!')
    
    example_list = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
    for i in range(len(example_list) + 1):
        logger.info('loop cnt = ' + str(example_list[i]))
    
    logger.info('example lambda finish!')

example_listの要素数分のinfoログを出力後、要素数 + 1のループ回数にしてあるので最後のループでIndex Errorで必ず落ちる内容です。

2. SNSトピックの作成

次は上記Lambdaの実行時エラーを拾うCloudWatchAlarmの作成ですが、まずはCloudWatchAlarmの通知先に指定するSNSトピックを先に作成します。
今回はここも設定を弄る必要がない為、全てデフォルト設定のexample_sns_topicというSNSトピックを作成しました。

まだサブスクリプションを作成していないので、この段階ではまだサブスクリプションが登録されていません。

3. CloudWatchAlarmの作成

通知先SNSトピックができたので、次はLambdaの実行時エラーを拾うCloudWatchAlarmの作成です。
対象リソースに手順1で作成したexample_lambdaを、実行時エラーを拾うので対象メトリクスにはErrorsを、アクションの通知先には手順2で作成したexample_sns_topicをそれぞれ指定したexample_alarmというアラームを作成しました。

一分間に一回以上エラーが発生するとアラームステータスに遷移し、ステータスがOKからアラームに遷移したタイミングで通知を送信するようにしています。

4. Slack Channelの作成

続いて、通知先のSlack Channelを作成します。
今回は、example_slack_channelというチャネルを作成しました。
既に通知したいチャネルが存在する場合は、このステップは省略します。

作成するチャネルは、publicチャネルでもprivateチャネルでもどちらでも大丈夫です。

5. AWS Chatbotの作成

今回の本題、AWS Chatbotを作成します。
マネジメントコンソールからAWS Chatbotの管理画面に入り、新しいクライアントを設定ボタンから種別にSlackを選択して連携の確認画面に進みます。

Allowボタンで連携を許可すると、Slackのワークスペースとの連携は完了です。
ワークスペースまで今回の為に新規作成するのは少し面倒だった為、プライベートテスト用の既存のワークスペースを使います。

設定済クライアントに連携したSlackのワークスペースが表示されるようになるので、選択した状態で新しいチャネルを設定ボタンからチャネルの作成に移ります。

通知先チャネルに手順4で作成したexample_slack_channelを、トピックには手順2で作成したexample_sns_topicをそれぞれ指定したexample_chatbot_channelというチャネルを作成しました。

また、IAMロールには以下のポリシーを設定したCUSTOMChatBotRoleという自作のロールを設定していますが、AWS Chatbotの新規チャネル作成時のデフォルトのポリシーテンプレートのポリシーにCloudWatchLogsReadOnlyAccessのポリシーを加えただけの最小権限のロールです。
CloudWatchLogsReadOnlyAccessのポリシーが何故必要かは後述します。

ZSH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "cloudwatch:Describe*",
                "cloudwatch:Get*",
                "cloudwatch:List*",
                "logs:Describe*",
                "logs:Get*",
                "logs:List*",
                "logs:StartQuery",
                "logs:StopQuery",
                "logs:TestMetricFilter",
                "logs:FilterLogEvents"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

以上で設定は全て完了です。

動作確認

必要なリソースが一通り作成完了したところで、一番初めに作成したLambda(example_lambda)をテスト実行させてエラーで落とします。
エラー発生から少し待つと(最大で1分程)、通知先に用意したSlackチャネル(example_slack_channel)に以下のようなメッセージが届くはずです。

届かない場合はどこかの設定が漏れているか間違っている可能性が高い為、手順1から見直してみて下さい。

ここが便利!と感じた内容

便利な点はいくつかありますが、以下2つが特に便利だと感じました。

1. 実行ログやエラーログがSlack上で確認できる

動作確認欄に記載したキャプチャ画像からも分かりますが、受信した通知内容の下部にShow logs、Show error logsという二つのボタンが存在しており、このボタンを押すだけでエラー発生時のLambda関数実行ログやエラーログが確認できます。

これがとにかく便利で、自分には一番刺さりました。

例えば、帰宅途中の電車の中でアラート通知を受信した場合、アラートの詳細を確認するのがとても大変だった経験をしている方は多いのではないでしょうか?
(自分は何度も経験済で、何かいい方法はないかなぁといつも思っていましたw)
Datadogなどの各種モニタリングツールへのリンクURLが通知内に含まれている場合は多いと思いますが、携帯端末の小さな画面で見るのはやはり大変です。

それが、このボタンを押すだけで実行時ログをSlack上で確認する事ができます!


このログをCLIから取得する際のコマンドまで記載してくれていてとても親切!



エラーだけのログも確認できるので、先にこちらを見てスタックトレースだけでは判別が難しい場合にINFOまで含めた前後ログを見ると対応効率が良さそうです。

  • このログを見る為に必要なこと
  • こちらのログを出力する為に、内部的にはAWS Chatbotのチャネル作成時に設定したロール(今回は、CUSTOMChatBotRole が該当)を使用して,
    CloudWatchLogs Insights queryを実行しています。
    従って、同ロールに設定するポリシーの中にCloudWatchLogsに対するクエリ実行権限が含まれていないと、ボタンを押してもパーミッションエラーになってしまいます。
    IAMロールにCloudWatchLogsReadOnlyAccessのポリシーをアタッチしていたのはこれが理由です

  • このログを見る時に意識すること
  • 上記でも書いた通り内部的にはCloudWatchLogs Insights queryを実行している為、CloudWatchLogs Insightsの課金形態がクエリ実行課金の都合上、ログを見る毎に料金が発生する事は意識する必要があります。
    一回のログ取得の料金は本当に微々たるもの(0.0076$/GB)なので、よほど凄い使い方(1日に数十回、数百回もアラート通知が飛んできて都度ログを確認したり、Show logsボタンを意味もなく連打したりなど)をしなければほぼ問題ない金額内で収まると思いますが、料金が発生するという事実は頭の片隅に入れておく必要があります。

2. 作成するのがとても簡単

Lambdaで発生した実行時エラーをSlackに通知しようとした場合、AWS Chatbotの登場前はSNSのサブスクリプションにLambda関数を登録し、SNSにpublishされたメッセージをSlackに通知する処理を自前で作成する必要がありました。
作成時のテンプレートなどがあればある程度作成工数は削減できたものの、LambdaからSlack通知する処理を作ろうとした場合を考えると、通知先チャネルのIncoming webhook用URLをパラメータストアに登録したり、同パラメータストアの値を取得する為のIAMポリシー/ロールの作成などなど、単調作業ではあっても必要な工程が沢山あるので結構面倒だったのが正直な感想でした。

これがAWS Chatbotに置き換えられると、SNSのサブスクリプションに登録するLambdaの作成が不要になるだけでなく、Incoming webhook用のURL登録も不要になりますし、もちろん登録したURLを取得する為のIAMポリシー/ロールの作成も不要になり対応工数が激減します。
手順に慣れてくると全工程含めて5~10分程度で完了するようになるので、これは本当に便利だと感じました。

今後への期待

インフラリソースはやはりコード管理したいので、Terraform対応してくれると嬉しいなー(CloudFormationはあるけど、Terraform使っているところも多いと思うので)とか、対応サービス拡充して欲しいなー(LambdaからSNSに直接publishした時も使えるようにして欲しいなどなど)など、こうなるといいなーと思う点はありますが、どれもそう時間が経たない間に対応されていきそうなので今後が本当に楽しみです!

Tweet
このエントリーをはてなブックマークに追加
Pocket
LINEで送る

カテゴリー: AWS, Chatbot, CloudWatchAlarm, Lambda, Slack, SNS タグ: AWS Chatbot, CloudWatchAlarm, Lambda, Slack, SNS

profile

profile_img Web系のソフトウェアエンジニアです。
野球観戦(横浜DeNAベイスターズ)、格闘ゲーム、カメラ、ランニング、愛犬、インテリア、美味しいものの食べ歩き、などなどが好き。

  • twitter MasakiMisawa
  • facebook MisawaMasaki
  • github MasakiMisawa
  • instagram masakimisawa
  • follow us in feedly

search

recent entry

  • M1 MacでAppleシリコンとIntelプロセッサのバイナリ管理を分離して共存させる
  • M1 MacでtfenvからTerraform1.0.2未満のダウンロードに失敗する問題を無理矢理解決する
  • GitHub ActionsからAWS利用時に永続的クレデンシャル情報を渡さないようにする
  • TerraformでAuroraのエンジンバージョンアップグレードをする時は、対象リソースをクラスターだけに絞る
  • CloudWatch Logsに出力されたエラーログ本文のSlackへの転送

category

  • AWS (17)
    • ACM (1)
    • AWS CLI (1)
    • Chatbot (2)
    • CloudWatchAlarm (1)
    • CloudWatchLogs (1)
    • CodeBuild (3)
    • DynamoDB (1)
    • IAM (1)
    • Kinesis (2)
    • Lambda (5)
    • OpenId Connect (1)
    • RDS (1)
    • S3 (2)
    • SNS (2)
    • SSM (2)
    • STS (1)
  • CI (2)
  • GCP (1)
    • PageSpeedInsights (1)
  • Git (3)
    • GitHub (2)
      • GitHub Actions (1)
  • M1 Mac (2)
  • Python (2)
  • Redis (1)
  • selenium (1)
  • Slack (3)
  • Terraform (3)
  • その他 (1)

archive

  • 2022年2月 (3)
  • 2021年1月 (1)
  • 2020年12月 (1)
  • 2020年11月 (1)
  • 2020年9月 (2)
  • 2020年8月 (1)
  • 2020年7月 (1)
  • 2020年6月 (1)
  • 2020年5月 (2)
  • 2020年4月 (1)
  • 2020年3月 (1)
  • 2020年1月 (1)
  • 2019年1月 (1)
  • 2017年12月 (1)
  • 2017年9月 (1)
  • 2017年8月 (1)
  • 2017年7月 (1)
  • 2017年2月 (1)
  • 2016年10月 (1)

tag cloud

ACM Aurora AWS AWS CLI Billing CI CloudWatchAlarm CloudWatch Logs CodeBuild Code Format Docker DynamoDB EC2 env find firehose Git GitHub GitHub Actions Homebrew husky IAM Role Java kinesis KinesisFirehose Lambda lint-staged M1 Mac Node.js OpenId Connect PHP Python RDS Redis RI S3 Selenium Slack SNS SSM Terraform tfenv セッションマネジャー リモートワーク 生産性

Copyright © 2025 public memo.