目次
- 目次
- 前提
- Slack bot を作ることにする
- hit コマンドについて
- translate コマンドについて
- link コマンドについて
- short コマンドについて
- 作成中に悩んだ部分
- 利用する場合に注意する部分
- まとめ
前提
9月に入って時間が取れたので AWS Cloud Development Kit (AWS CDK)
を触ってみることにしました。というのも、TypeScriptでの実装例は結構な数見かけるのですがPythonの実装例は探し方が悪いのかあまり見当たらず・・・だったら自分で少し触ってみようかと。
AWS CDKを利用するシーンを考えると、構築や運用に深く関わる可能性が高いため AWS CDKのroadmapが公開されており、今後も継続して更新が続けられていく様子が確認できるところが非常に素晴らしいです。
というわけで、触れるタイミングで使ってみたので簡単にですがまとめてみました。
Slack botを作ることにする
CDKを使ってみると言っても、何か動くもので継続的に使ってアップデートできるものが題材にあるといい感じなので、普段利用しているSlackのbotを作ることにしました。
作るのであれば楽しく作って、実際に使えるものが良いので Amazon API Gateway
と AWS Lambda
の定番構成で、AWS SDK for Go
でLambda関数を作成しました。
Slackへのメッセージ送信は次のライブラリを利用しました
今回一番苦労したのは、このライブラリの利用でした。 SlackのAPI側と別名で定義されているメソッドや、APIで必須指定がないものが 必須になっていたりと、ちゃんと確認しながら進めないとダメな感じでした。
作ったbotは AWS Chatbot
と同様に、botにメンションを行いコマンドを実行する仕様としています。
コマンドの詳細はGitHubのReadmeファイルを確認してください
スクリーンショットで利用しているbotアイコンについては以下のサイトから取得しました。
次項からは簡単にコマンドの紹介を行いたいと思います。
hit コマンドについて
hit
コマンドは、Slackのチャンネルに参加しているメンバーからランダムで指定の人数を選択できます。
想定しているユースケースは、レビューメンバーの選出や会議のファシリテーターの選出になります。
実際に、リモートワークにシフトしてから ランダムに誰かを選択する
と言ったことが必要になることも多く、Slackのデフォルトアプリでも良い感じがします。
抽選のために専用チャンネルを作るのが運用としては良さそうな感じですが、既存のチャンネルで使いたい時に抽選対象ではないメンバーを指定できるような仕組みも実装しています。
translate コマンドについて
translate
コマンドは、Amazon Translate
を利用して日本語を英語に、日本語意外を日本語に翻訳できます。
想定しているユースケースは、SlackでRSS Feed を確認している場合に手軽に翻訳を行えるようにすることになります。
実際に、SlackでRSS Feedを確認していると場合によっては大量にステータスが更新されることもあり、手軽に翻訳できれば少しは便利になる感じがします。
以前に作ったSlackの国旗絵文字で翻訳する方法でも対応できるのですが、Slackのイベント発火がワークスペース全体となり、特定のチャンネルや条件で絞れないためワークスペースの参加者が多い、絵文字リアクションの利用が多い場合は、翻訳と関係ないイベントが大半となり Amazon API Gateway
と AWS Lambda
の実行回数が増えることになります。
link コマンドについて
link
コマンドは、botにメンションする際にSlackに添付したファイルをS3にアップロードして、ファイル取得が可能となる署名付きURL(Pre-Signed URL)を発行します。
想定しているユースケースは、メールに添付できないサイズのファイルの受け渡しや、ローカル環境からEC2インスタンスへのファイル持ち込みなどです。
実際に、EC2インスタンスにファイルを持ち込む場合は、対象のファイルをS3に一度アップロードして、EC2インスタンスでS3からファイルを取得する方法を取ることが多いのですが、対象ファイルをアップロードする手間がなくなるのは良い感じです。
署名付きURLの期限は指定可能となっていますが、今回はLambdaの実行にIAMロールを利用しているので、最大値はこの制限に依存します。
また、ファイルの添付は複数可能ですが署名付きURLについては1ファイル1URLとなります。これはS3の署名付きURLがオブジェクトに対して発行されているためです。 複数ファイルで1URLとしたい場合は、ファイル自体を圧縮するなど工夫をお願いします。
short コマンドについて
short
コマンドは、短縮URLを発行することができます。
想定しているユースケースは、前述の link
コマンドで発行した署名付きURLを短縮URLで短いURLに変換することになります。
実際に、署名付きURLはかなりの長さがあり、コピーミスで表示できない問題が起こったりしてました。短いURLにすることにより、単純なミスが減るのは良いか感じです。
署名付きURLに有効期限はあるのですが、短縮URLでも有効期限を指定することができます。
この短縮URLを発行する仕組みについては、以下のワークショップを参考にしています。 AWS CDKのワークショップとなるためCDK側のコードも非常に参考になります。
作成中に悩んだ部分
セキュリテイについて
- 今回Slackの認証トークはLambdaの環境変数に設定して利用している
- 内部のみの利用ということで手軽な方法で実装してある
- 本来ならば、AWSのキー管理ができるマネージどサービスを利用する方が良い
- 上記サービスを利用する場合には、CDK側のコードも変更するため今回は最小構成で作成した
Lambdaレイヤーの利用
- 短縮URLを作成する機能はSlack botに実装した
- 短縮URLにアクセスされた場合はSlack botとは別のLambdaに実装した
- これはLambdaに入ってくるイベントを内部振り分けるより簡潔になりそうだったから
- しかし、Lambdaを2つにしたことにより実装を共有したい部分が出てきた
- Lambdaレイヤー化を検討したが、利用言語がgolangであるためLL利用時のような大きなメリットはなさそう
- 結果として同じソースを利用することで対応してある
Slackからのリクエスト処理
- Slackからイベント内容が投げ込まれるが、3秒以内に応答しないと再送される
- 対応するためには、Slackからイベントを受け取ったらすぐに応答するか、1度投げ込まれたイベントには反応しないようにする
- APIGateway + Lambdaが同期処理されているため、今回は後者を採用した
Lambdaの非同期呼び出し
- 前述の通り、今回は同期処理だが非同期処理とすることも可能
- 非同期処理の場合は結果を戻すのに工夫が必要となるが、Lambda Destinationsの機能を利用できそう
- 当初は同期処理のままLambda Destinationsを利用しようとして、Destinations先のLambdaがキックされずに悩んだ
- 実際にはAPIGatewayの部分でSlackのchallenge認証に応答する必要がありそう
Slack APIについて
- Slackに参加しているメンバーを取得しようとすると、先に見つかるのがワークスペースに参加する全員を対象としたAPI
- このAPIだとSlack利用者が多い場合には時間がかかることが想定される
- 調べてみると会話の単位(チャンネル・DMなど)に参加しているメンバーが取得できるAPIがあった
- しかし、上記のAPIで取得できるのはユーザーIDだけ
- 加えてbotやワークフロー実行ユーザーが一覧に入っている模様
- ユーザー情報の詳細が取得できるので、その情報で人なのかを判別できる
- 今回はユーザーIDだけ必要だったので、一覧取得の時にbotユーザーをフィルタできる機能が欲しかった
テストコードについて
- LambdaとAWS CDKのテストコードをどうするか
- Lambdaの方はgoogle先生に聞いてみるといろいろ出てくるしMockでの対応でもなんとかできる
- CDKの部分はどうするばいいのか悩む
- と思ってたら、ちゃんと公式ドキュメントに記載があった
- 現状はどちらもテストコードがない状態なので対応が必要
利用する場合に注意する部分
今回は所属するチーム内での利用を想定し、チームで管理されてAWSアカウントに対してデプロイを行っています。そのため仕様上で考慮する部分などは共有できている前提で利用を想定しています。
もし、ご自身の環境で利用していただける場合には以下の部分に注意をお願いします。
AWS Lambdaの仕様に依存
メモリ容量に依存
- 確保されているメモリ容量に、添付ファイルの最大ファイル容量が依存する
- 現在のメモリ設定は2GB
- Lambdaの現時点での最大メモリ容量は3GB
- 確保メモリ以上のファイルサイズがある場合は添付しても失敗する
- この制限を突破するためには、アーキテクチャの変更が必要
実行時間に依存
- Lambdaの現時点での最大実行時間は15分
- 現在の実行時間設定も15分
- Slackチャンネルの参加メンバーが多数の場合は実行時間をオーバーする可能性がある
- 添付ファイルが極端に大きい場合は実行時間をオーバーする可能性がある
- 実行時間はこれ以上延長はできないので、内部の仕組みを改善して対応する必要がある
Amazon DynamoDBの仕様に依存
キャパシティユニットに依存
- 現在はOn-Demand Modeで動作
- キャパシティは自動拡張されるため、料金が比例して増加する可能性がある
TTLの仕様に依存
その他
構築について
削除について
- AWSリソースはAWS CDKで削除される
- 事前に作成したRoute 53ドメインのゾーンは削除されない
- CloudWatch Logsに出力されたログは削除されない
- S3はbucketが空でないと削除できないため、削除を行わない
- その他の関連リソースは自動削除される
- データを保持する必要がある場合には、事前にバックアップを取得するころ
- 完全に削除するには。上記の削除されないリソースを手動で削除する必要がある
まとめ
- AWS Cloud Development Kit (AWS CDK) を使ってみたかった
- せっかくだから普段使っているSlackのbotを作った
- 作ったbotは普段使えて、ちょっと便利になる感じを目標にした
- ランダム選択はそこそこ出番がある感じ
- CDKはとても便利で楽しい
- CDKの実装例はTypeScriptが多い気がする
- 個人的にはPythonで書きたいのでもう少し実装例を増やして欲しい
- CDKで書いたコードをどうテストするか悩んだ
- CDKを利用することで、今回のようなSlack bot開発もほとんどマネジメントコンソールにアクセスせずに進められて捗る
- 今後も機会があれば積極的にCDKは使っていきたいと思った
- やっぱり手を動かしているのは楽しいです
以上になります。