AWS Chatbot とは
ざっくりと言ってしまうと、AWS上で起きた事象を Slack や Amazon Chime に通知したり、スラッシュコマンドなどで操作できたりするものです。
本稿執筆時点では、ベータ版のため、この資料の 1.10 Beta Service Participation に則り、これ以上の言及は致しません。
背景
現時点では、Slack と Amazon Chime のみの対応のため、Microsoft Teams 用として AWS Chatbot っぽいものを作ろうということです。
ベータが外れたころに採用されてるといいなぁと願いながら...
レシピ
登場人物
- Microsoft Teams
- AWS Lambda
- Amazon SNS
- Amazon CloudWatch
Slackでいうところのスラッシュコマンドのようなものを実装するなら Amazon API Gateway も使います。
Microsoft Teams の設定
AWS からの通知を受け付ける設定をします。
通知を受け付けたいチームのチャネル右側の[...]をクリックします。
すると、以下のようなメニューが表示されるので[コネクタ]をクリックします。
コネクタの一覧が表示されたら[Incoming Webhook] の構成ボタンをクリックします
最後にお好みに応じてイメージをアップロードして、「作成」ボタンをクリックします
作成が完了すると、AWS からの通知を受け付けるURLが生成されるので、コピーして控えておきます。作業が終わったら[完了]ボタンで閉じます。
このURLは後続の AWS Lambda上のコードに使用します。
URL を控えるのを忘れても、再度、コネクタの画面を表示し、左側の「構成済み」からたどることができます。
コネクタが作られたチャネルには、以下のような記事がポストされます。
AWS Lambda 上のコード
※今回は、CloudWatch メトリクスのアラームを受けて、それを Microsoft Teamsに送付するサンプルです。
※Lambdaに入っていないモジュールとして、PIL(pillow) と requests を使用しています。
※適宜配置してください。
※Python3.8 で動作確認しています。
import boto3
import json
import io
import base64
from PIL import Image
from io import BytesIO
import requests
teams_endpoint = 'Microsoft Teamsの設定で控えておいたURLを指定する'
# URLは必用に応じてKMSなどを利用して暗号化したり、環境変数機能をご利用ください。
def lambda_handler(event, context):
subjet = event['Records'][0]['Sns']['Subject']
# SNS が送信するJson内のMessage要素以下はStringなのでJsonとして読み込む
message = json.loads(event['Records'][0]['Sns']['Message'])
newStateReason = message['NewStateReason']
newStateValue = message['NewStateValue']
nameSpace = message['Trigger']['Namespace']
metricName = message['Trigger']['MetricName']
topicName = event['Records'][0]['Sns']['TopicArn'].split(':')[5]
resourceId = message['Trigger']['Dimensions'][0]['value']
resourceType = message['Trigger']['Dimensions'][0]['name']
# Microsoft Teams にポストする内容をつくる
text = []
text.append(newStateReason)
text.append("\r\n\r\n")
text.append("**Alarm State:** {0} **Name Space:**: {1}".format(newStateValue, nameSpace))
text.append("**Metric:** {0} **Topic Name:** {1}".format(metricName, topicName))
text.append("\r\n\r\n")
# 対象のメトリック画像を取得する
cw = boto3.client('cloudwatch')
widget = '{\
"view": "timeSeries",\
"stacked": false,\
"metrics": [\
[ "'+ nameSpace +'", "'+ metricName +'", "'+ resourceType + '", "' + resourceId +'" ]\
], \
"width": 480,\
"height": 180,\
"start": "-PT2H",\
"end": "P0D",\
"timezone": "+0900"\
}'
response = cw.get_metric_widget_image(MetricWidget = widget)
img = Image.open(BytesIO(response["MetricWidgetImage"]))
# メモリ上に画像を格納するおまじない
buffer = io.BytesIO()
img.save(buffer,"PNG")
# メモリ上に保存した画像をBASE64エンコードする
imgBase64 = base64.b64encode(buffer.getvalue()).decode().replace("'", "")
# BASE64エンコードした文字列を Microsoft Teams へ送信する内容に追加
text.append("![Chart](data:image/png;base64,{0})".format(imgBase64))
# Microsoft Teams へ送信する下ごしらえ
request = {
'title': subjet,
'text': '\r\n\r\n'.join(text)
}
# Microsoft Teams へ送信する
response = requests.post(teams_endpoint, json.dumps(request))
Amazon SNS の設定
トピックの作成
Amazon SNS の画面を表示させ、[トピックの作成]ボタンをクリックします。
名前や表示名を指定します。その他必要な設定があれば実施し、[トピックの作成]ボタンをクリックします。
サブスクリプションの作成
トピックの作成が完了すると、以下の画面が表示されるので、[サブスクリプションの作成]ボタンをクリックします。
プロトコルに「AWS Lambda」を選択します。
そして、エンドポイントで先ほど作成した AWS Lambda の Lambda関数を指定し、その他必要に応じて設定を行い、[サブスクリプションの作成]ボタンをクリックします。
Amazon CloudWatch アラームの設定
Amazon CloudWatch の画面を表示し、左側にある「アラーム」をクリックします。
アラームの一覧が表示されたら、[アラームの作成]ボタンをクリックします。
フィルタ条件を指定するフィールドに、通知したいEC2インスタンスのインスタンスIDを指定し、Enterキーを押します。
すると、以下のように EC2>インスタンス別メトリクス のみになるのでクリックします。
通知したいメトリクスを選択します。この例では、CPUUtilization (CPU使用率)を選択しています。
選択したら、画面下部の[メトリクスの選択]ボタンをクリックします
メトリクスの条件設定を行います。
通知したい条件を設定します。この例では、CPU 使用率が 80 を超えたら通知が出るようにしています。
[次へ]ボタンをクリックして進めます。
SNS トピックは先ほど作成したものを利用するので、
[既存の SNS トピックを選択]を選択します。
そして、[通知の送信先]に作成したものを指定します。
[次へ]ボタンをクリックして進めます。
アラームの名称を指定します。任意のもので構いません。
[次へ]ボタンをクリックします。
プレビューと作成画面が表示されるので、設定内容を確認して、
画面をスクロースして、[アラームの作成]ボタンをクリックします。
テスト
色々と設定が終わったら、Cloudwatch アラームを発火させます。
アラームを設定した EC2 インスタンスが Linux であれば、以下のコマンドを実行することで、簡単にCPU使用率をあげることができます。
sudo yes >> /dev/null &
[1] 10968
少し待つと、 Microsoft Teams 以下のような記事が追加されます。
テストが終わったら、プロセスを kill
してください。
まとめ
コミュニケーション基盤が Slack や Amazon Chime ではなく Microsoft Teams のため、すぐに AWS Chatbot の恩恵にあずかれない!と悲しんでいる方も、この作例をもとに、ニッコリ笑顔になっていただけたら幸いです。
参考資料
https://hacknote.jp/archives/51333/
https://qiita.com/m_hama123/items/c40c8f5271ca03fc57e9