Serverless Framework で AWS Chatbot と Amazon SNS のリソースを作成してみた
はじめに
こんにちは、サービスグロースチームの筧です。
「大量の Lambda 関数から CloudWatchLogs の Error などを取得して Slack に通知したい」
って思ったことありませんか? ソリューションの一つとして、Lambda 関数を CloudWatch アラームでモニタリングし、Amazon SNS 経由で AWS Chatbot で通知する方法があります。
Lambda 関数を 、AWS Chatbot で通知を受け取る | Amazon Web Services ブログ
上記ブログののソリューションでは、モニタリングしたい Lambda 関数を指定したい際に、 CloudFormation のパラメータに、Lambda 関数名をカンマ区切りリストで入力しています。 こちらのソリューションの利用を検討した際に、モニタリングしたい Lambda 関数をパラメータ入力ではなく、 自動的に追加されるような機能があれば、メンテナンスが減って更に良いなと思いました。
現在、上記を実現するべく PoC を作成しています。PoC の内容は以下の通りです。
- 以下のリソースを Serverless Framework の resources として作成
- Amazon SNS Topic
- AWS Chatbot SlackChannelConfiguration
- IAM Role(上記 AWS Chatbot 設定用の IAM Role)
- 以下の機能を持つ Lambda 関数を Serverless Framework の functions として作成
- CloudWatch アラーム未設定の Lambda 関数に、CloudWatch アラームを自動設定機能
- 作成した CloudWatch アラームを一括削除機能
今回は前者の Serverless Framework の resources を作成する箇所をご紹介します。 後者の functions は次のブログで紹介予定です。
前提
筆者の環境
% sw_vers ProductName: macOS ProductVersion: 12.2.1 BuildVersion: 21D62 % sls --version Framework Core: 3.19.0 (local) 3.19.0 (global) Plugin: 6.2.2 SDK: 4.3.2 % pipenv --version pipenv, version 2022.6.7
やってみた
AWS Chatbot から Slack への接続を確立
AWS Chatbot から Slack への接続を確立は、コンソールで事前に設定しておく必要があります。 設定方法は先程紹介したブログを参照ください。 Slack チャンネル ID とワークスペース ID を利用するのでメモしておきます。
Lambda 関数を 、AWS Chatbot で通知を受け取る | Amazon Web Services ブログ
ワークスペース ID を取得するには、コンソールの AWS Chatbot サービスにアクセスしてください。
チャットクライアントで AWS Chatbot の設定を開始するには、AWS Chatbot コンソールで [Configure new client] を選択し、[Amazon Chime] または [Slack] を選択します。 セットアップウィザードで Slack OAuth 2.0 のページにリダイレクトされます。右上隅で設定する Slack ワークスペースを選択し、「Agree」を選択します。Slack ワークスペースが AWS Slack アプリをインストールします。 ワークスペース ID を書き留めておきます (例:T01UXHUCRMW)。これは、後で CloudFormation テンプレートをデプロイするときに必要になります。 Slack チャンネル ID を取得するため、デスクトップアプリまたはウェブ上の Slack にアクセスしてください。チャンネルを右クリックして、リンクをコピーします。コピーされたリンクの最後の部分がチャネル ID です(たとえば、C01U80K9KPD)。
パラメータストアの設定
上記でメモした Slack チャンネル ID とワークスペース ID を AWS Systems Manager のパラメータストアに格納します。
- Slack チャンネル ID
- 名前: /alert-lambda/ステージ名/SLACK_CHANNEL_ID
- 値(例): C01U80K9KPD
- ワークスペース ID
- 名前: /alert-lambda/ステージ/SLACK_WORKSPACE_ID
- 値(例): T01UXHUCRMW
serverless.yml
service: alert-lambda frameworkVersion: '3' provider: name: aws runtime: python3.9 lambdaHashingVersion: 20201221 stage: ${opt:stage, 'dev'} region: ${opt:region, "ap-northeast-1"} memorySize: 256 iam: role: statements: - Effect: 'Allow' Action: - 'ssm:GetParameter' - 'sts:AssumeRole' - 'logs:DescribeLogGroups' - 'cloudwatch:DescribeAlarms' - 'cloudwatch:PutMetricAlarm' - 'cloudwatch:DeleteAlarms' - 'lambda:ListFunctions' Resource: - '*' environment: ${self:custom.environment} functions: add: handler: src/handlers/add.handler timeout: 300 delete: handler: src/handlers/delete.handler timeout: 300 create_error: handler: src/handlers/create_error.handler timeout: 60 plugins: - serverless-step-functions - serverless-python-requirements - serverless-prune-plugin stepFunctions: ${file(includes/state-machines.yml)} custom: pythonRequirements: usePipenv: true prune: automatic: true number: 3 environment: STAGE: ${self:provider.stage} SLACK_CHANNEL_ID: ${ssm(${self:provider.region}):/${self:service}/${self:provider.stage}/SLACK_CHANNEL_ID} SLACK_WORKSPACE_ID: ${ssm(${self:provider.region}):/${self:service}/${self:provider.stage}/SLACK_WORKSPACE_ID} SNS_TOPIC_ARN: Ref: AlertLambdaTopic package: patterns: - '!./**' - ./src/**/*.py resources: Conditions: CreateTokyoResources: Fn::Equals: - !Ref AWS::Region - ap-northeast-1 Resources: AlertLambdaTopic: Type: "AWS::SNS::Topic" Properties: DisplayName: "AlertLambda-${self:provider.stage}-${self:provider.region}" TopicName: "AlertLambdaTopic-${self:provider.stage}-${self:provider.region}" AlertLambdaChatbotRole: Type: "AWS::IAM::Role" Condition: CreateTokyoResources Properties: RoleName: "AlertLambdaChatbotRole-${self:provider.stage}" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: chatbot.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: "AlertLambdaChatbotPolicy-${self:provider.stage}" PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - cloudwatch:Describe* - cloudwatch:Get* - cloudwatch:List* - logs:Describe* - logs:Get* - logs:List* - logs:StartQuery - logs:StopQuery - logs:TestMetricFilter - logs:FilterLogEvents Resource: - "*" AlertLambdaChatbot: Type: "AWS::Chatbot::SlackChannelConfiguration" Condition: CreateTokyoResources Properties: ConfigurationName: "AlertLambdaChatbot-${self:provider.stage}" GuardrailPolicies: - "arn:aws:iam::aws:policy/CloudWatchReadOnlyAccess" IamRoleArn: !GetAtt AlertLambdaChatbotRole.Arn LoggingLevel: INFO SlackChannelId: "${self:custom.environment.SLACK_CHANNEL_ID}" SlackWorkspaceId: "${self:custom.environment.SLACK_WORKSPACE_ID}"
- provider.iam.role には、次回作成する Lambda 関数で必要なロールなどを定義しています。
- 環境変数の SLACK_CHANNEL_ID と SLACK_WORKSPACE_ID は、Serverless Framework で用意されている構文を使い、パラメータストアに保管したクレデンシャル情報を参照しています。SLACK_CHANNEL_ID には通知先の Slack チャンネル ID を値に設定します。SLACK_WORKSPACE_ID には、AWS Chatbot の設定時に作成された ワークスペース ID を値に設定します。
Reference Variables using the SSM Parameter Store | Serverless Framework
- resources で定義した、Amazon SNS Topic の ARN は Ref を利用して環境変数で参照しています。このやり方については以下のブログもよかったら参照ください。
Serverless Framework で resources に定義したリソースを環境変数で参照しようとした時に、エラーが発生した場合の対処方法 | Serverless Framework
おわりに
最後まで読んでいただきありがとうございます。
- 以下の機能を持つ Lambda 関数を Serverless Framework の functions として作成
- CloudWatch アラーム未設定の Lambda 関数に、CloudWatch アラームを自動設定機能
- 作成した CloudWatch アラームを一括削除機能
上記内容は以下のブログを参照ください。
既存の大量の Lambda 関数に、Errors と Throttles メトリクスのアラーム通知設定を自動で行う
本ブログが少しでも皆さんの役立っていると幸いです。 それではまた!