先月末にようやくAWS Lambdaの承認されて遊べるようになりました!
さっそくAWS Lambdaを堪能しているのですが
なんだこのGUIは・・・。
これでコードを書けなくはないのですが、正直言ってこれでコードを管理できる気が全くしません・・・。(Google App Scriptの悪夢の再来
プロジェクトをzipにしてアップロードするにしてもデバッグが死ねるのが目に見えています。
という訳で本気で遊ぶためにGitHub+TravisCI環境に合わせたプロジェクトテンプレートを作りました。
開発サイクル
開発サイクルは2つのサイクルを回しながら進めていくことを想定しています。
1つ目はローカル単独でユニットテストを実行しながらビジネスロジックを作成していくサイクル。
2つ目はAWS Lambdaで実際に動かしながらAWSに依存した処理を作成していくサイクル。
それぞれについて解説していきます。
ローカル実行
ローカルでユニットテストを実行するのは他の方も書いている通り、requireをするだけでhandlerを実行することができます。(handlerの名称は変更可能なのでexportsでも良い気はしますが)
lambda-templateではnpm run test
で同様の処理を実行します。
ソースを変更する度にコマンドを実行するのも面倒臭いので、npm run debug
でソースの変更を監視しながら実行することができます。
AWS Lambdaに依存する処理には向かない方法ですが、素早く実行を行えるため全体をざっくり組んだり、ビジネスロジックを書くときに重宝します。
AWS Lambdaの実行
AWS Lambdaでの実行を行う場合は以下の処理をタスク化する必要があります。
- プロジェクトをzip形式にアーカイブ
- アーカイブしたファイルをAWS Lambdaにアップロード
- AWS Lambdaを実行
- CloudWatchLogsから実行結果のログを取得
- (アップロードしたAWS Lambdaを削除)
それぞれをどうやっているのかはlambda-templateの/tasks/plugins/grunt-lambda-runner
のコードでも見てください。(面倒臭くてプラグインをまだ切り出してないです)
この一連の処理を実行するとAWS Lambdaで定期実行を行えるようになります。
lambda-templateではnpm run run
で実行できます。
ソースの変更を監視しながら実行はnpm run launch
で実行することができます。
実行速度がかなり遅いのでこれをメインに開発を進めるのはツラいのですが、本番環境と同じ環境でデバッグを行えるので、細かい処理の動作確認をしたり、AWS Lambdaに依存するところを確認するのに良い感じです。
余談ですが、実行後に数秒またないとログをCloudWatchLogsから取得することができないため、どうしてもwaitを挟まないといけないのがツラいです。
AWS Lambdaで実行後に素早くログを取得する手段が欲しいですね。
ついでにconsole.error
でも普通のログが出るとか止めて欲しい・・・。
リリースサイクル
開発サイクルの定義が出来たので、ついでにTravisCIを使ってCI、CDを環境を作ってリリースサイクルを回せるようにします。
とはいえ開発サイクルを作るさいに作った
- プロジェクトをzip形式にアーカイブ
- アーカイブしたファイルをAWS Lambdaにアップロード
上記のタスクでCDを定義すればリリースサイクルに必要なタスクを出来上がります。
lambda-templateではnpm run publish
で実行できます。
あとは.travis.yml
にテストタスクを実行し、成功したらデプロイするように記述するだけです。
ちなみに今回はmasternのみのブランチ戦略を取ってます。
Git FlowやGitHub Flowを行うときはbranchesの指定を増やして、デプロイをmasterブランチでのみ行うようにすれば済みます。
TravisCIはAWS CodeDeployにも対応してたりするので、AWS Lambdaにも対応してくれればこのあたりの記述がもっと簡素に出来るんですけどね。
課題
- AWS Lambdaの実行が遅い
- 実行時間の長い処理のログを全て取得できない(StartからEndまでを取るようにする?)
- ソース変更の監視をしながらAWS Lambdaの実行を何度もおこなうとエラーが発生する
正直言ってAWS Lambda localが欲しいです。
おわりに
いかがでしたでしょうか。Google App Scriptのあの地獄を思えばGitHub+TravisCIな構成を作りやすいAWS Lambdaは優秀ですね。
もう少し作り込んだら、gruntプラグインを切り出したり、Yeomanのジェネレーターを作ったり、Scala.jsに対応しようかなと思います。
正直、まだイケてるサイクルに成りきれてないので、もっとこうした方がとかあればぜひご意見ください。