セキュリティ

Lambdaで発生したエラーをAWS Chatbotを利用してSlackに通知する

どうもkakeruです。本記事では、LambdaのエラーをChatbotを利用してSlackに通知する方法について記載しています。また、このブログは、下記ブログを参考にして作成しています。

CloudFormation で AWS Chatbot と CloudWatch Alarm を定義してSlackにアラート通知してみた https://dev.classmethod.jp/articles/cloudformation-chatbot-alarm-to-slack/

概要

CloudFomationを利用して、Lambda用のCloudWatch AlarmとSNSトピックをそれぞれ作成し、Slackへ通知します。以下図を参照。

参考ブログでは、LambdaごとにCloudWatch Alarm用のSNSトピックを作成しています。本ブログでは実際のユースケースに合わせて、複数のLambdaに対して、1つのSNSトピックを作成し、Slackへ通知できるように設定しています。

AWS ChatbotとSNSトピックを作成する

Slackワークスペースの認証とワークスペースID取得

  • WebコンソールでAWS Chatbotにアクセスし、チャットのクライアントで[Slack]を選択し、[クライアントの設定]をクリック。

LambdaNotification_01

  • AWS ChatbotがSlackワークスペースにアクセスするための権限を与えるために[許可する]を選択する。

LambdaNotification_02

  • 下記のワークスペースIDはあとで必要なのでメモしておく。

LambdaNotification_03

SlackチャンネルIDを取得

  • Slack通知を行いたいチャンネルを右クリックしリンクをコピーを選択する。

LambdaNotification_04

  • このリンクをメモ帳などに貼り付ける。下記文字列の最後がチャンネルIDなのでメモしておく。

    https://<テナント名>.slack.com/archives/<チャンネルID>

YAMLの作成

  • chatbot_stack.ymlを作成する。
  • ワークスペースIDとチャンネルIDは外部から渡す。
AWSTemplateFormatVersion: "2010-09-09"
Description: Chatbot Stack

Parameters:
  TargetWorkspaceId:
    Type: String

  TargetChannelId:
    Type: String

Resources:
  # CloudWatch Alarm用のSNSトピック
  CloudWatchAlarmForChatbotTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: cloudwatch-alarm-for-chatbot-topic

  # Chatbotの定義
  CloudWatchAlarmForChatbot:
    Type: AWS::Chatbot::SlackChannelConfiguration
    Properties: 
      ConfigurationName: ChatbotForCloudFormation
      IamRoleArn: !GetAtt ChatbotIamRole.Arn
      LoggingLevel: INFO
      SlackChannelId: !Ref TargetChannelId
      SlackWorkspaceId: !Ref TargetWorkspaceId
      SnsTopicArns: 
        - !Ref CloudWatchAlarmForChatbotTopic
        
  # Chatbotで利用するIAMロールを定義
  ChatbotIamRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: chatbot-iam-role
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: chatbot.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: chatbot-iam-policy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - cloudwatch:Describe*
                  - cloudwatch:Get*
                  - cloudwatch:List*
                  - logs:*
                Resource:
                  - "*"

Outputs:
  CloudWatchAlarmForChatbotTopicArn:
    Value: !Ref CloudWatchAlarmForChatbotTopic
    Export:
     Name: !Sub ${AWS::StackName}-CloudWatchAlarmForChatbotTopicArn

Slack上でログを取得できるようにChatbot用のIAMロールにCloudWatch Logsを参照するための権限を付与しています。

デプロイ

  • 以下のコマンドでデプロイする。
  • TargetWorkspaceIdとTargetChannelIdに先ほどコピーしておいたワークスペースIDとチャンネルIDを指定する。
aws cloudformation deploy 
    --region ap-northeast-1 
    --template-file chatbot_stack.yml 
    --stack-name LambdaErrorForChatbotStack 
    --capabilities CAPABILITY_NAMED_IAM 
    --parameter-overrides TargetWorkspaceId= TargetChannelId=

デプロイ完了

LambdaNotification_05

LambdaのErrorを監視するCloudWatch Alarmを作成する

YAMLの作成

  • 下記CLoudFormationの[Description]、[AlarmName]、[Value]を書き換えて、YAMLを作成する。
  • YAMLを監視対象となる下記Lambdaの数だけデプロイする必要がある。YAML名とStack名は任意とする。
AWSTemplateFormatVersion: "2010-09-09"
Description: 

Resources:
  # CloudWatch Alarmの定義
  LambdaFunctionErrorsAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: <対象のLambda名>-lambda-error-alarm
      Namespace: AWS/Lambda
      Dimensions:
        - Name: FunctionName
          Value: <対象のLambda名>
      MetricName: Errors
      ComparisonOperator: GreaterThanOrEqualToThreshold  # 閾値以上
      Period: 60  # 期間[s]
      EvaluationPeriods: 1  # 閾値を超えた回数
      Statistic: Maximum  # 最大
      Threshold: 1  # 閾値
      TreatMissingData: notBreaching  # Errorsがない場合は良好として扱う
      AlarmActions:
        - Fn::ImportValue: !Sub LambdaErrorForChatbotStack-CloudWatchAlarmForChatbotTopicArn # アラーム遷移時のアクション
      OKActions:
        - Fn::ImportValue: !Sub LambdaErrorForChatbotStack-CloudWatchAlarmForChatbotTopicArn  # OK遷移時のアクション

デプロイ

YMALを格納しているディレクトリまで移動後、上記のYAML名とStack名を記載し、次のコマンドを実行してデプロイする。

aws cloudformation deploy 
    --region ap-northeast-1 
    --template-file [YAML名] 
    --stack-name [Stack名]

デプロイ完了

  • 1分後、通知先のSlackチャンネルにOKアラームが通知されればデプロイ完了。

LambdaNotification_06

プライベートチャンネルに通知する場合

  • 対象のプライベートチャンネルにて[/invite @aws]と入力

LambdaNotification_07

ログの確認方法

  • Error通知が届いたら通知の下部にある[show logs]または、[show error logs]を選択する。

LambdaNotification_08

  • しばらく経つと、ログがslackに通知される

LambdaNotification_09

終わりに

今回は、Lambdaの標準メトリクスErrorsを監視対象としてCloudWatch Alarmを作成しましたが、カスタムメトリクスを利用すれば、AWS上の色々な情報を取得できるので応用してみるといいかもしれません。

kakeru

こんにちは、セキュリティチーム所属の新米エンジニアkakeruです。業務で少しでも役に立つ情報をブログに書いていきますので、よろしくお願いします。