前置き
ちょっと前からLamveryというAWS Lambdaのデプロイや管理を簡単にするツール(OSS)を作っていて、Qiitaでも紹介させてもらったりしていたのですが、結構便利に使えるようになってきてはいるものの、最近出てきたApexの注目度 1 が非常に高くて嫉妬したので比較記事を書いてみることにしました。
Lamvery
の説明についてはこちらをご確認ください。
http://qiita.com/marcy-terui/items/1617ab4e20e3339d1930
https://github.com/marcy-terui/lamvery/blob/master/README.md
Apex
はwikiを見るとなんとなく雰囲気がつかめるかと思います。
https://github.com/apex/apex/wiki
一方が自作なので、できるだけ公平を期したいとは思っていますが、Lamvery側に寄ってしまっていたらお察しください。また、作者としての解説と見解も載せさせていただきます。ご参考までに。
あと、Apexは対抗心から色々把握してるつもりですが、誤りなどあればご指摘いただけれると助かります。
下記、2016年1月29日現在の比較です。
基本部分の比較
項目 | Apex | Lamvery |
---|---|---|
実装言語 | Go | Python |
インストール方法 | バイナリダウンロード | PyPi,rpm,deb |
対応ランタイム(Lambda) | Go, Python, Node.js | Python, Node.js |
管理対象 | Project単位 | Function単位 |
設定ファイルフォーマット | JSON | YAML + jinja2 |
解説と見解
実装言語
好みの問題ですね。
インストール方法
Apex
インストール方法はGoゆえに依存ごとバイナリ化されていて、ダウンロードして置くだけのApex
が強いでしょうか。
Lamvery
Python
+ pip
環境のセットアップが必要。そこから先はpip
で、依存ごとまとめて1コマンドでインストールできます。2
また、CI環境などで使うためにPythonまで含めて完全に独立した環境を作れるyumとdebのパッケージも提供してます。
https://github.com/marcy-terui/lamvery#installation
対応ランタイム(Lambda)
Apex
Apex
はLambdaが公式では対応していないGolang
に対応しているのが特徴です。他にもBabel等のAltJS系に対応しているようです3
Lamvery
Lamvery
では特に要望がなければGo
をサポートするつもりはないです。4
Node.js
は自分がPython
メインなので今のところ試験的なサポートです。4
公式がGo
対応するのはそう遠くない未来だと思ってるんですがどうでしょうね?
みんなそんなに非公式な方法でもいいから使いたいものなのかな・・・?
管理対象
Apex
Apex
は複数のLambda Functionを一つのProjectでまとめて管理でき、Projectに適用する設定ファイルと個々のFunctionに適用する設定ファイルとがあります。
Lamvery
Lamvery
はFunction単位でしか管理できません。ここは今後どうするか考えている所です。
ただ、Function単位であるため、Python限定ではありますがvirtaulenv
5仮想環境内でそのFunctionが使用するライブラリのみをインストールしておけば、それを自動的に格納効率を考慮して収集し、アップロードするようにしています。これは、Apex
はただ特定のディレクトリ以下を全てアップロードするだけなので、Lambdaのソースコード容量に制限があることを考えれば大きな違いなのではないでしょうか。Python限定ですが。。。6
設定ファイルフォーマット
Apex
ただのJSON
です。
Lamvery
YAML
ですが、テンプレートエンジンであるjinja2を被せています。
つまり、変数埋め込みや動的な記述をサポートしています。
機能比較
項目 | Apex | Lamvery |
---|---|---|
Deploy | ○ | ○ |
Rollback | △ | ○ |
任意のAliasの設定 | ☓ | ○ |
実行(Invoke) | ○ | ○ |
除外リスト | ○ | ○ |
機密情報受け渡し | ○ | ◎ |
CloudWatch Events(スケジュール実行) | ☓7 | ○ |
CloudWatch Logs(実行ログの閲覧) | ○ | ○ |
CloudWatch Metrics(起動時間など) | ○ | ☓ 8 |
解説と見解
両方にある機能の中で、特徴的な違いがある部分のみ記載します。
Deploy & Rollback
Lambdaの特殊なバージョニングの仕様は以下が分かりやすいので目を通しておくと良いかと思います↓
http://dev.classmethod.jp/cloud/aws/lambda-versioning/
Apex
バージョニング9が必須です。Deploy時に current
というAliasを設定し、Rollback時には最新の一つ前のバージョンにcurrent
を付け替えることで実施します。
ですが、このApex
の手法はAliasの付け替えをdeploy,rollback以外で行うと破綻します。それだけならまだ良いのですが、deploy,rollbackを二度繰り返しても破綻します(下記参照)
最後は「2」に戻って欲しいのにFailしてしまうことが分かっている「3」に戻ってしまいます。一応、Rollback時に任意のバージョンを指定するオプションは用意されていますが、バージョン番号を人間が覚えておかないといけないというのはナンセンスだと思います。
Lamvery
Lamvery
では、上記の問題があるため、別の方式を採用しています。
簡単に言うと、Deploy時に前のバージョンにも別のAliasを付けておき、そこに対してRollbackします。一時的に2つ以上前のバージョンに巻き戻したりするような運用を可能とするためです。
また、任意のAliasを付ける機能もあるので、組み合わせて使用することで柔軟なバージョン管理ができます。
Apexと同じようにシンプルに使いたければ、バージョニングを有効にしたままDeployとRollbackだけを使えば良いだけです。
Rollbackを使用する場合はバージョニングが必須ですが、使用しない場合は設定ファイルでオフにできます。また、デプロイ時に設定するAliasも任意に設定できます。
これも、先にも述べたLambdaの容量に制限があることを踏まえれば必要なオプションだと思っています。軽微な修正ではオフにしておいて、必要な時にオンにしてロールバックできるようにするということもできます。
実行(Invoke)
Apex
単発起動と、標準入力から入力を次々受け付けて(Streaming)、連続で同期実行10することができる。
Lamvery
単発実行のみ。Streamingは非同期実行10して、ClouodWatch Logsをtailするような形で形でサポートしたいと思ってます。
機密情報の受け渡し
Apex
Deploy時に環境変数として指定します。バージョン管理11に含めることはできません。
ソースやWikiを見る限りPythonが対応していないような・・・?
Lamvery
KMSを利用し、暗号化した機密情報を設定ファイルに含めてバージョン管理10できます。
現状はPythonのみのサポートですが、近いうちにNode.jsにも対応したいと思っています。
Node.jsも対応しました(2015.02.03)
所感とまとめ
今のところ、全体的には一長一短という感じかと思います。
ただ、ロールバックの仕様とCloudWatch Events対応は大きな違いだと思うので、日本語サポート可能12という点も踏まえてApex
だけではなく、Lamvery
にも目を向けていただければ幸いです :-) 13
-
GitHubのスター数、Apexの日本語記事とLamveryのQiita記事のはてブ数を比べると。。。 ↩
-
pip
はRubyで言う所のgem
, Node.jsで言う所のnpm
です。pyenv
でPythonをインストールすると標準で入ってるし、Linux系ならデフォルトのパッケージマネージャから入れられることが多いです ↩ -
Node.jsからGoのバイナリを子プロセスとして立ち上げて、標準入出力を使ってやり取りするような方式で対応している ↩
-
ライブラリ等を共有しない独立したPython実行環境を作ることができるPythonライブラリ ↩
-
自分がPythonメインで使っているからで、Node.jsに詳しい方がアイデアだけでもいただければ対応はしたい ↩
-
近日対応予定 ↩
-
Lambda的には
publish
オプション ↩ -
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax ↩ ↩2 ↩3
-
LambdaのじゃなくてGitとかの方 ↩
-
というか日本語の方が助かる ↩
-
「Apexを超えてやる!」って思ってるけど、あまりにも見向きされないとモチベーションが続かないかもしれないw ↩