Apex を使った AWS Lambda のデプロイの基本

業務で初めて Lambda を使うことになりました。
その際に Lambda のデプロイや管理に Apex という OSS を利用したので
その基本的な使い方を備忘録として書きます。
# Lambda とは  
AWS の [Lambda の公式ドキュメント](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html)にも説明がありますが、サービスの概要は以下のとおりです。

* 実行したいコードをユーザーの代わりに実行してくれるコンピューティングサービスの一種  
* Lambda の処理の主なランタイム環境は **Java 8、Python 2.7、node.js v4.3.2** 
* Lambda の処理は基本的にイベント駆動で実行される<sup>※1</sup>
* 実行環境やインフラ等のリソースの手配・管理は AWS が勝手にやってくれるのでユーザーは気にしなくて良い  
* Lambda の実行環境ではメモリや実行時間には制限がある（メモリは最大 **1.5GB**、実行時間は最大 **300秒**）
* コストも処理実行のたびに課金されるので、EC2 のように起動しているだけで課金される心配はない  

※1 : S3 にファイルがアップロードされた、Dynamo DB が update された等のイベント  
# Apex とは  
[Apex](http://apex.run/) は Lambda をビルド・デプロイ・管理するための OSS です。
今回 Lambda を使うにあたって、私が使用したツールです。
ちなみに、Apex の他にも Lambda をデプロイしたり、管理する方法はいくつもあります（**下記参考記事**）。 
 
* [AWS LambdaファンクションをGulpでデプロイ](http://dev.classmethod.jp/cloud/aws/how-to-deploy-a-lambda-function-with-gulp/)  
* [AWS Lambda Pythonをlambda-uploaderでデプロイ](http://dev.classmethod.jp/cloud/deploy-aws-lambda-python-with-lambda-uploader/)  
* [Kappa: AWS Lambdaへのデプロイを容易化する](https://www.infoq.com/jp/news/2015/01/kappa-lambda)  
* [AWS Lambda向けデプロイ・管理ツール「Lamvery」について](http://qiita.com/marcy-terui/items/1617ab4e20e3339d1930)
* [AWS Lambdaを活用したServerless Frameworkを触ってみる](http://qiita.com/susieyy/items/1c2af0ef7b88b742c37a)  
   * こちらは純粋な Lambda の管理というよりサーバレスアーキテクチャを作るための包括的なツールなので、やや毛色は違うかも

# Apex を実際に使って Lambda をデプロイする

ここからは Apex を使って実際に自作の Lambda Function を任意の AWS 環境にデプロイするまでの基本的な流れを紹介します。
（Lambda のランタイムは node.js を想定しています）
Apex の詳しい使い方については [こちら](http://dev.classmethod.jp/cloud/aws/how-to-manage-aws-lambda-functions-with-apex/)の記事がとても参考になりました。

### AWS のクレデンシャルを取得・設定しておく  
----  
まずは Lambda をデプロイする AWS アカウントの自身の IAM ユーザーのクレデンシャル情報を設定します。
AWS CLI を使用する場合と同様の方法で設定が行えます。
「IAM ユーザー？」、「クレデンシャル？」、「AWS CLI？」となった方は、まずは AWS のことをちょっと調べたほうがいいかもしれません。  
Windows の方は `C:\Users\USERNAME\.aws\config`、`C:\Users\USERNAME\.aws\credentials` にクレデンシャル情報を記載しておきます。
`[default]
output = json
region = ap-northeast-1
[default]
aws_access_key_id = XXXXXXXXXX
aws_secret_access_key = XXXXXXXXXX`
### Apex を自分の環境に用意  
----  
次に Apex を実行できる状態にしましょう。  

* OS が Windows や Linux の方  
  1. Apex の実行ファイルを[ここ](https://github.com/apex/apex/releases)から取得します   
 （私は Apex v0.10.3 の apex_windows_amd64.exe をダウンロードしました）
  2. 実行ファイル名を変更します<sup>※2</sup>   
  3. 実行ファイルを任意の場所に置いて、パスを通します
* OS が MAC の方  
下記のコマンドで `user/local/bin` に Apex の実行ファイルがインストールされます  
``
curl https://raw.githubusercontent.com/apex/apex/master/install.sh | sh
``  

※2 : Apex をコマンドで呼び出すときに元の実行ファイル名だと長いので変更するだけで必須ではありません 

### Apex のプロジェクトを作成する  
----  
Lambda をデプロイ・管理するための Apex プロジェクトを作成します。  
1. Apex プロジェクト用のディレクトを作成
`$ mkdir myApexProject`
`$ cd myApexProject`
2. Apex プロジェクトの初期化
`$ apex init //Apex コマンドの実行ファイルを apex にリネームしてる` 

![apex init.PNG](https://qiita-image-store.s3.amazonaws.com/0/89967/574d32df-e931-b0d5-87e9-9353c20012fc.png)

このとき、クレデンシャルを設定した AWS アカウント上に今後デプロイする Lambda に付与する IAM ロールや IAM ポリシーが自動で作成されるようです。  

Apex プロジェクトのディレクトリ構成は下記のとおり 

![tree.PNG](https://qiita-image-store.s3.amazonaws.com/0/89967/fbd63f54-8469-203f-1049-87aefa519336.png) 
### Function を作る  
----  
AWS 上で動かしたい Lambda Function を作成します。
といっても、今回はデフォルトで作成される `Hello` という function を
`MyFunction` という名前に変更して使うことにします。
そこで、`myApexProject/functions` 配下の `Hello` というディレクトリを
`MyFunction` というディレクトリに変更します。
(`MyFunction`  配下の index.js は下記の通り)

```js:index.js 
console.log('starting function')
exports.handle = function(e, ctx, cb) {
  console.log('processing event: %j', e)
  cb(null, { hello: 'world' })
}
```  
Lambda が検知したイベントの詳細を CloudWatch に出力して、Lambda には `{"hello" : "world"}` を返すだけの簡単な Function です。
### Function をデプロイする  
----  
最後に Lambda をデプロイしてみましょう。
1. project.json と同階層にカレントディレクトリを変更
2. デプロイコマンドを入力(Cygwin でやったら出力が文字化けしました)
`apex deploy MyFunction`  

![deploy.PNG](https://qiita-image-store.s3.amazonaws.com/0/89967/48a0702a-02a2-ba25-2af7-41638800d28a.png)

クレデンシャルを設定している AWS アカウントの Lambda Function 一覧を参照すると `myApexProject_MyFunction` という Lambda Function がデプロイされています。　
　
![deployedLambda.png](https://qiita-image-store.s3.amazonaws.com/0/89967/458f2f77-7375-d0ae-cceb-a0b0b4c59585.png)   
# 終わりに  
今回は Apex での Lambda のデプロイ機能だけを紹介しましたが、Apex には deploy 以外にも Function の一覧を取得する `list` や Function を削除する `delete` や Function を実行する `invoke` 等、まだまだいろいろな機能があります。
（私自身が deploy 以外あまり使いませんでしたが。。）

Apex 自体はまだ ver 0.x で、まだまだ発展途上(?)のツールかもしれませんが、Lambda を扱う際には一度使ってみてはいかがでしょうか。