AWSからSlackへの通知はChatbotを使おう!

# AWSからSlackへの通知はChatbotを使おう!

Slackの一定プランではチャンネルごとにメールアドレスを払い出せるため、私用で利用しているチャンネル以外はシステム通知に利用していました

AWSで利用していたときはLambdaのエラー通知やSQSでのデッドレターキューにたまったことや、EC2を利用していた環境が落ちた時の検知などです

AWSにはChatbotサービスがあり、これを利用するとより込み入った設定が行える他にSlack側からアクションを取れることを知ったので詳細に見ていきます :eyes: 

とりあえず、何かしらの通知を送る目的で一通り設定して進めていきましょう

チャンネル単位で作成できる

## 一通りの流れ
1. 適当なSNSトピックを作成
1. Chatbotからクライアントの設定としてSlackを選択
1. Slackのアプリ連携画面で許可をだす
1. チャンネルの追加・設定諸々実施
1. 送信をテストする

### 適当なSNSトピックを作成
ChatbotからSlackへ通知を飛ばす際にトリガーとしてSNSを利用します
```mermaid
flowchart LR
    A[何かしらのイベント]
    B[SNS]
    C[Chatbot]
    D[Slack]

    A --> B
    B --> C
    C --> D
```


なのでまずはAWSのSNSから[トピックの作成](https://ap-northeast-1.console.aws.amazon.com/sns/v3/home?region=ap-northeast-1#/create-topic)を行います
この後Lambda経由で通知するのも行なっていくので LambdaNotifyと付けておきます
![スクリーンショット 2024-12-18 0.32.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/71b52b31-fb3e-dc15-469d-70cc1f5e9c40.png)


サブスクリプションはChatbotの方で作成するので、トピックが作られたかどうかだけ確認しておきましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/eb5e352d-83c0-cff5-72d5-a1192abcfe68.png)


### Chatbotのクライアント設定としてSlackを選択
次はAWS Chatbotの画面へ移動し、ChatbotのクライアントとしてSlack連携を進めましょう

画面右のチャットクライアントからSlackを選択し、「クライアントを設定」へ進みます
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/90b85bb0-3dbb-a6aa-fb52-c627b3343f4f.png)

ブラウザ側でSlackにログインしている場合はこのように表示されると思います
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/390c8042-7a84-5f04-d50f-ad5036fcd4b3.png)

許可するを選択するとSlackのワークスペースが追加されます
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/07acdff4-9691-2391-bf24-2837cf713726.png)


### チャンネルの追加を行う
続いてはチャンネルへの連携を行ないます

ここでは下記のことを設定していきます
- 設定名(自由記述可)
- Slackチャンネル名
- IAMロール名
- SNSのトピック

それぞれ
- notification-only
- あらかじめ自身のSlackで作成しておいたチャンネルの「awsのためのチャンネル」
- AWSChatbot-role
- LambdaNotify

を設定します

![スクリーンショット 2024-12-18 0.41.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/b5f57814-6989-d2b1-46cf-f470b5797a42.png)

![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/d348ee90-7453-8a13-5e6f-558b80c5d063.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/f109a6bc-5b7a-6395-0cfb-92846d90f327.png)

:::note info
チャネルロール:チャンネル単位(今回は「awsのためのチャンネル」単位)でロールを割り当てるため、どのSlackアカウントだろうと一律で同じことができる
:::

:::note info
ユーザーレベルのロール: Slackのチャンネルにて↓のようなメッセージが表示され、チャンネルに参加しているユーザー単位で権限を柔軟に変更できる

![スクリーンショット 2024-12-18 23.28.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/3cada18f-097c-cea7-8b5d-17f1367118b3.png)
:::


:::note
チャネルガードレールポリシー: チャネルロールおよびユーザーロールで実施する動作が
誤って予想していないような動作をすることを防ぐ目的のため設定した枠組みから超えないようにするポリシー
(名前の通りガードレール的な役割)
:::

各種入力後にチャンネルの作成を押して↓のようにチャンネルに紐つくChatbotが作成されます

![スクリーンショット 2024-12-18 22.43.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/0e32ac7d-3812-78a4-3efa-6950f11f0fae.png)


### 送信をテストする
このままテストメッセージを送信してみます

このようにSlackメッセージが受信できれば確認完了です

![スクリーンショット 2024-12-18 22.46.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/dce480f1-4e54-036e-59c2-f434d4499779.png)

つぎはLambdaが失敗した時の通知を設定していきます

## Lambdaが失敗したときの通知について

Lambdaの失敗通知についてはCloudwatchAlarm経由で行います

先ほどはこの順番で処理を行っていましたが
```mermaid
flowchart LR
    A[何かしらのイベント]
    B[SNS]
    C[Chatbot]
    D[Slack]

    A --> B
    B --> C
    C --> D
```

何かしらのイベントとして作用するのがCloudwatchAlarmで、そのAlarmが参照する指標としてLambdaを設定する形になります
```mermaid
flowchart LR
    X[Lambda]
    Y[CloudwatchAlarm]

    B[SNS]
    C[Chatbot]
    D[Slack]
    X --> Y
    Y --> B
    B --> C
    C --> D
```

追加で必要なことはLambdaを作ってCloudwatchAlarmを設定し、通知先をSNSのLambdaNotifyに設定を行うだけなので詳細は省きます

あらかじめLambdaが1分間に5回以上Errorを検出したときにCloudwatchAlarmが鳴るように設定しておき、意図的にLambdaでエラーを発生させると下記のようなSlackメッセージが届きます

![スクリーンショット 2024-12-18 23.19.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/724d1171-5841-0a85-9d9a-ee31eab42ed2.png)

これで通知が届くことを確認できます、さらにshow logsやshow error logsを選択するとSlack上でLambdaのログを見れます

実際に show logsを選択すると↓の画像のようにログが表示されます
![スクリーンショット 2024-12-18 23.23.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/e2804be9-7dbe-41d6-02ab-e619126fd773.png)

:::note warn
実際にlogを取得する場合
このSlackチャンネルに送信するChatbotの権限として「CloudWatch Logsへのアクセス権限」が必要です
今回だとnotification-onlyという設定名に紐つく `AWSChatbot-role`を変更してあげる必要がある
:::


### CloudwatchAlarmを介して通知する理由

↓の画像はLambdaの送信先設定画面です、こちらにSNSトピックが送信先として存在するのにわざわざCloudwatchAlarmを経由させるのはなぜでしょうか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/74bf4dd7-731d-318e-43ad-c98233eb2856.png)


それは送るメッセージがChatbotの認識できるメッセージ形式の必要があります
仮に意図しないデータ形式の場合は下記のように not supported と言われてメッセージが飛んでこないままになります

```log:cloudwatch log
Event received is not supported (see https://docs.aws.amazon.com/chatbot/latest/adminguide/related-services.html ): 
{
    "subscribeUrl": null,
    "type": "Notification",
    "signatureVersion": "1",
    "signature": ........
```

[カスタム通知のイベントスキーマ](https://docs.aws.amazon.com/chatbot/latest/adminguide/custom-notifs.html#event-schema)に沿って送信するとChatbotが認識できるメッセージ形式で好きなメッセージを送信できます

https://docs.aws.amazon.com/chatbot/latest/adminguide/custom-notifs.html#event-schema

## まとめ
Slackの無料プランでもAWSからの通知を受け取れる方法でした
「どんなメッセージでも簡単に送れるし受け取れる！」というわけではないものの、一定AWSが気を利かせてSlackメッセージを送信してくれるのでとりあえずで使っていきたいですね

後、料金について書いてませんでしたがChatbotを利用するだけは費用がかからず
その周辺のSNSやCloudwatchAlarmなどには費用がかかるのでそこだけ気にしておきましょう