社内の自動テスト実行に使っているSlackアプリをHubotからBoltに移行したのでその際の流れや詰まりどころを話します。 BoltがLambdaからEC2のJenkinsサーバを叩いている点が典型的な構成とは少し異なり、詰まったところでもあるので、同じ構成の人の助けになればと思います
Hubotについて
Hubotとはチャットボットの開発や実行を行うフレームワークです。
freeeではStaging環境に向けて自動テストを実行したいときのChatOpsとしてHubotを利用しています。具体的にはSlackで決められたメッセージを送信します。Slackのメッセージの最初にqabotとつけると反応するようにしてあるので、qabot [実行したいテスト名]
のようにSlackで打つことでHubotがEC2上にあるJenkinsを叩いて自動テストを実行しています。
課題
自動テストで使っているHubotアプリには以下の課題がありました
- CoffeeScriptベースなので社内に慣れてるメンバーが少なく、触るハードルが高い
- EC2インスタンスの管理が必要。OSやミドルウェアのアップデートなど
- EC2インスタンスをずっと起動しておく必要があり、無稼働の時でもコストがかかる
- Hubotの開発が最近あまり活発でない(hubot-slackは開発が進められているが)
これからの課題を解決するためにHubotからBoltへの移行を行いました。
Boltについて
BoltとはSlackのための開発ツールでJS, Python, JavaのSDKがあります。
- TypeScriptで使える
- サーバーのメンテナンスが不要
- Lambda上で動くので必要なときだけ実行される
Boltを使えばHubotの課題を解決できると感じたので今回利用することにしました。
Hubotベースの仕組みからからBoltベースの仕組みへ移行するためにやったこと
優先度が高かったのが脱CoffeeScriptだったので、まずはCoffeeScriptを外すことを優先しました。そこからBoltで動くようにロジックを変更して、最後にTypeScriptに移行しました。
- CoffeeScriptからJavaScriptに移行
- ロジックをHubotからBoltに移行
- JavaScriptからTypeScriptに移行
1. CoffeeScriptからJavaScriptに移行
一気にTypeScriptに移行することはせず、CoffeeScript -> JavaScript -> TypeScriptと段階的に移行しました。 CoffeeScriptからJavaScriptへの移行はdecaffeinateを利用しました。 decaffeinateは機械的に変換するのでJavaScriptが冗長になることがあり、合わせて修正を行いました。
2. ロジックをHubotからBoltに移行
BoltはHubotと書き方が結構違うのでドキュメントを一通り読むのをオススメします。移行については公式のMigration Guideがあるのでそちらが参考になります。 slack.dev
3. JavaScriptからTypeScriptに移行
JavaScript-> TypeScriptはHubotからBoltに移行する際に合わせて行いました。 (公式ドキュメント)https://slack.dev/bolt-js/ja-jp/tutorial/using-typescriptはあるのですが、特に詳しく書かれていないので、自力で進めていく必要があります。
EC2からLambdaに移行するにあたって
インフラをEC2からLambdaに変更する際に詰まったところや変えたところについて説明します
EC2上にあるJenkinsが叩けない
BoltはLambdaにデプロイしているのでEC2が配置されているVPCの外にあり、VPC内に入れたとしてもでもネットワークのやりとりも制限されているのでLambdaからのリクエストが弾かれてしまいます。
対応方法
まずはLambdaをVPC内に配置します。しかし、同一VPCであってもネットワークのやりとりは制限されているので、これだけではLambdaからのリクエストは弾かれてしまいます。
その後LambdaにElastic IPを付与、JenkinsのEC2に割り当てているSecurity Groupに付与したIPアドレスを許可させました。
詳しくは以下の記事が参考になりました- Lambda 関数、Amazon VPC、およびサーバーレスアーキテクチャを使用して、静的アウトバウンド IP アドレスを生成します - AWS 規範的ガイダンス
- VPC の Lambda 関数へのインターネットアクセスを許可する
構成をサーバレスに変更
デプロイされているファイルを編集して上書きするコマンドがありました。Hubotの時はEC2上にデプロイしたファイルを読み込み-> 書き込みしていたのですが、BoltはLambda上にデプロイしており、S3上にファイルがある方が取り回しが楽なので変更しました
対応方法
まずはEC2にあったファイルをS3に配置して、Lambda 関数が Amazon S3 にオブジェクトをアップロードすることを許可する Lambda 実行ロールを作成。その後、S3から読み込み-> 書き込みするように変更しました。
最後に
素直にLambdaだけで完結させるのであれば公式ドキュメントだけで移行できました。そこから社内のユースケースに合わせて修正するのが大変なんだよなぁと思った開発でした。