AWS Lambdaでサーバーレス楽しんでるみなさん。
私の所属するJX通信社では、AWS Lambdaを結構活用しています。Lambdaのデプロイ管理のために、個人的にはApexというツールを使っているので、今回はその紹介をしたいと思います。
TL; DR
Lambda使うならApex使おう
Lambdaやってて発生する辛み
Lambdaを継続して使ってくると、だいたいこんな辛みがでてきます。
- Lambda関数が増えてくるので管理が大変
- Lambda関数を更新するために必要なステップが多すぎる
Lambda関数を更新するためには、だいたい次の作業が発生してきます。
- pip install とか npm install とかして、依存ライブラリをインストール
- ソースコードと依存ライブラリを一つのzipに梱包
- S3にアップロード
- Lambda関数を更新
- 必要であれば、エイリアスを更新
- 実行して動作を確認
- CloudWatch Logsを見て動作を確認
というところで、これを自動化したくなってくるわけですが、それを自動化してくれるOSSが既に存在しています。本稿で紹介するApexもそのようなツールの一つです。ここでは「デプロイ管理ツール」と呼称します。
デプロイ管理ツールの分類
デプロイ管理ツールはいくつかあります。awesome-servelessというリポジトリが参考になりますが、デプロイ管理ツールを分類すると、
- 特定の言語(ランタイム)に依存するか、全ての言語に対応するか
- アップロードだけか、それ以外の機能も備わっているか
- インフラ管理をする機能が備わっているか
- API Gatewayの管理をする機能が備わっているか
- 依存ライブラリの管理をする機能が備わっているか
- 関数を呼び出したり、ログを確認したり、ロールバックの機能があるか
Apexはその中でも、「全ての言語に対応(というかGoにすら対応!)」「アップロード以外に、ログ確認や呼び出し機能も含む」「Terraformと連携してインフラ管理ができる」「API Gatewayの管理や依存ライブラリ管理の機能は備わってない」という分類のツールです。
参考にするべきページ
何か困ったら、Githubで検索すると良いです。
使い方の紹介
Apexにはinitスクリプトが入っているので、簡単に始めることができます。使い方を知るために、まずは空のプロジェクトから始めると良いです。
# インストール curl https://raw.githubusercontent.com/apex/apex/master/install.sh | sh # 初期化 apex init
apex init
すると、次のようなディレクトリができます。
. ├── functions │ └── hello │ └── index.js ├── infrastructure │ ├── dev │ │ └── main.tf │ └── modules │ └── iam │ ├── iam.tf │ └── outputs.tf └── project.json
このうち、project.jsonが設定ファイルで、infrastructureはterraformで扱うコード、functionsがLambda関数です。functionsの下のディレクトリと、デプロイされるLambda関数が、一対一に対応します(つまり、 {プロジェクト名}_hello
というLambda関数がデプロイされる)。
デフォルトのhello関数は index.js
が入っているので、当然nodeランタイムが選択されます。main.py
だったらPythonが選択されます。ランタイムの推論ルールはソースコードで確認できますが、function.json
を変更することで、ランタイムや、ハンドラー関数を明示的に指定することもできます(このあたりは、Githubで検索するとわかりやすいかも)。
Terraformは、terraform hogehoge
の代わりに、 apex infra hogehoge
のように扱います。そうすることで、関数名のARNとかがうまい感じにTerraformに引き渡されます。
デプロイ
apex deploy
こうすると、デフォルトで current
というエイリアスが貼られて、全ての関数がデプロイされます(コードが変更されてなければ、もちろんデプロイされない)。--alias
フラグとかをつけると、エイリアスを明示的に変えることも出来ます。
呼び出し
apex invoke hello < event.json
渡すJSONを指定して、上記のように呼び出せます。
ログの確認
呼び出した際、当然ログを確認したいですね、ということで、ログの確認は下記のようにします。tail -f
のようにしたい場合は、-f
フラグをつけます
apex logs hello # または apex logs -f hello
Apexの悪いところ
- dev, prod のような環境管理が、別アカウントであることが前提になっている。つまり、Lambdaのエイリアスであったり、API Gatewayのステージで環境管理をすることがあまり想定されていない
- Terraformを使ったことがない人には、Terraformの学習コストが高い。ただし、Terraformを使わずにGUIでポチポチインフラ管理をすることももちろんできる
- Pythonのpipのサポートが特にない(というかnode以外のサポートが薄い? ちなみに作者はJS界隈で有名な @tj さん)
ApexのTips
Apexの悪いところをあげてみたのですが、回避策もあります。そんなTipsを紹介します。
強制的にデプロイする
デプロイする際、--alias
というフラグをつけるとエイリアスをcurrent
以外にできると紹介しました。しかし、次のようにすると、コードが更新されていないためにデプロイされません。
# currentを更新 apex deploy # devを更新、、、されない! apex deploy --alias dev
こういうときは、--set
という環境変数を変更するためのフラグを使って、強制的にコードが変わった状態を作ってデプロイすると良いです。
# currentを更新 apex deploy # 環境変数を入れるために、コードが変更されるので、devが更新される! apex deploy --alias dev --set tekitounahensuu=dev
Pythonで使う
先ほども述べたとおり、pipとかrequirements.txt のための仕組みは特にありません。
Apexでは、 functions
というディレクトリ規約で、関数をデプロイします。つまり、functions というディレクトリをうまく使ってあげるといろいろできます。言い換えると、functionsディレクトリはビルド用ディレクトリ(コミットしないディレクトリ)として割りきりましょう
例えば、次のようなディレクトリ構成を考えます。
. ├── functions │ └── hello │ └── .gitkeep ├── infrastructure ├── project.json └── src └── hello ├── main.py └── requirements.txt
src
というディレクトリを作りました。例えば、apex deploy
する前に、次のようなステップを踏んであげれば、「requirements.txtの依存関係をインストール」「ソースコードのディレクトリを綺麗にする」という2つの要望がかなえられます。
1. pip install -r requirements.txt -t functions/hello して、依存ライブラリをインストール 2. cp -r hello functions/ して、ソースコードをfunctions下にコピー 3. apex deploy すると、functions/hello の中身をデプロイしてくれる
ちなみに、Apexにはhookの仕組みがあるので、活用すると良いと思います。
Javaで使う
Javaの場合は、apex.jar
というファイルがあれば、それをデプロイします。つまり、こんな感じ。
. ├── functions │ └── hello │ └── apex.jar ├── infrastructure ├── project.json └── src └── hello └── 適当にJavaプロジェクトとか作ればいいじゃない
同じように、ソースコードは functions
以外で管理しましょう。jarさえ作れば良いので、ScalaだろうとClosureだろうとGroovyだろうと(たぶん)動きます(Scalaしかやったことないけど)。
APIの管理にはTerraformを使わない
突然ですが、TerraformのAPI Gatewayの管理は貧弱です。貧弱というか、「ステージへデプロイをする」ということを想定していない作り、だと思います。
API Gatewayは幸いなことにSwaggerによる管理ができるようになっています。これをインポートするための公式ツールもあるので、これを使うと良いでしょう(awslabs/aws-apigateway-importer: Tools to work with Amazon API Gateway, Swagger, and RAML)。
ちなみにSwaggerによるインポートに対応する予定はあるみたいです。
まとめ
いろいろ書いてきましたが、Apexというツール自体、高速に動くし、便利だし、縛りも少ないし、おすすめです。
日本で一番Apexで苦しんできたかもしれないので、何か質問などあればTwitterとかでメンションください。
ところで、JX通信社では素敵なPythonistaや素敵なiOSエンジニア募集中です。