はじめに
最近、花粉の影響かわかりませんが、涙と鼻水がどこからともなく、発生して困っております。
アプリケーションサービス部の森です。
今回は、CloudWatch AlarmをSlackに投稿する仕組みの紹介となります。
これまで、アラームが発生したら、Amazon SNS経由でE-Mailに送ってなどのやり方がありましたが、
CloudWatch Alarmでアラームが発生したら、Amazon SNS経由でAWS Chatbotを使って、
Slackチャンネルにアラーム情報を投稿するやり方を書きます。
前提条件
その1:Slackに関する情報収集
まずは、Slackに関する情報を集めます。
必要なものは以下の2つ
- ワークスペースID
- 使われるSlackワークスペースのID
- チャンネルID
- アラーム情報を投稿するSlackチャンネルのID
確認方法は以下になります。
① SlackにWebブラウザでアクセス
② 投稿したいSlackチャンネルをクリック(今回は例として #random チャンネル
以下の画像のようになります。
赤線と緑線を引いています。
赤線が「ワークスペースID」(例として、「T」から始まり、「/」の前までが対象)
緑線が「チャンネルID」(例として、「C」から始まり、URLの最後までが対象)
となります。

後ほど利用します。
その2:AWS ChatbotからSlackへのアクセスを許可
次に、AWS ChatbotとSlackを連携させるためのアクセス許可を実施します。
① AWSマネジメントコンソールにログインし、AWS Chatbotを開きます。
② 右上にある「新しいクライアントを設定」をクリックします。



念の為、メモしたワークスペースIDと同じかも確認してください。

アラームをSlackに通知するための準備
Slack通知までできる状態になりましたので、Amazon SNSとAWS Chatbotのデプロイをしていきます。
Amazon SNS
最近、IaCで作業することが多いため、CloudFormation Templateを用意しました。
SNSのARNは他でも利用するため、エクスポートする設定にしています。
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
SystemName:
Type: String
Default: templateproject
Environment:
Type: String
Default: dev
AllowedValues:
- prd
- stage
- dev
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
-
Label:
default: General
Parameters:
- SystemName
- Environment
Resources:
ChatbotSNS:
Type: AWS::SNS::Topic
Properties:
TopicName: !Sub ${SystemName}-${Environment}-alarm-chatbot
Outputs:
ChatbotSNSARN:
Value: !Ref ChatbotSNS
Export:
Name: !Sub ${SystemName}-${Environment}-ChatbotSNSARN
AWS Chatbot
こちらもCloudFormation Templateを用意しました。
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
SystemName:
Type: String
Default: templateproject
Environment:
Type: String
Default: dev
AllowedValues:
- prd
- stage
- dev
TargetSlackWorkspaceId:
Type: String
TargetSlackChannelId:
Type: String
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
-
Label:
default: General
Parameters:
- SystemName
- Environment
Resources:
AlarmChatbot:
Type: AWS::Chatbot::SlackChannelConfiguration
Properties:
ConfigurationName: !Sub ${SystemName}-${Environment}-Alert
IamRoleArn : !GetAtt WebAPIAlertRole.Arn
LoggingLevel: ERROR
SlackWorkspaceId: !Ref TargetSlackWorkspaceId
SlackChannelId: !Ref TargetSlackChannelId
SnsTopicArns:
- Fn::ImportValue: !Sub ${SystemName}-${Environment}-ChatbotSNSARN
WebAPIAlertRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${SystemName}-${Environment}-Alert-Role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: chatbot.amazonaws.com
Action: sts:AssumeRole
Path: /
Tags:
- Key: Name
Value: !Sub ${SystemName}-${Environment}-Alert-Role
- Key: Application
Value: webapi
- Key: Category1
Value: webapi
- Key: Category2
Value: !Ref Environment
Policies:
- PolicyName: !Sub ${SystemName}-${Environment}-Alert-Policy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- cloudwatch:Describe*
- cloudwatch:Get*
- cloudwatch:List*
Resource:
- "*"
CloudFormationでテンプレートを実行
上記テンプレートを使ってCloudFormationから実行してAmazon SNSとAWS Chatbotを作成します。
パラメータについては、適宜変えてください。
ただ、 TargetSlackWorkspaceId にはSlackのワークスペースIDを入力し、
TargetSlackChannelId には投稿するSlackチャンネルIDを入力してください。
動作確認
今回は、Lambda FunctionとCloudWatch Alarmを利用します。
内容は省きますが、Lambda Functionは、すぐエラーが発生するロジックにし、
CloudWatch Alarmが発生したら、上記で構築したAmazon SNSに通知するように設定しています。
以下では、Lambdaの中で0で除算するようにしてエラーを発生させた例になります。
これでアラートがSlackに連携されました。

さいごに
CloudWatch Alarmでアラートが発生した場合に、Amazon SNS経由でAWS ChatbotからSlack連携してみました。
昔はメールで受け取っていたものを、Slackで連携していけるというのも時代が変わってきたなと痛感しています(もうnn年仕事してますので...
ということで、有効活用していただけますと幸いです。
2022/05/12 追記
上記は、Slackのパブリックチャンネルに対しての操作となります。 Slackのプライベートチャンネルを利用される場合は、該当のSlackチャンネルで以下のコマンドを実行してください。
/invite @aws