AWSでServerlessの環境をCIするための選択肢を調べたメモ

利用するサービスはAWSに限定するとした場合に開発・テスト・デプロイを継続するための選択肢をいくつか調べてみました。

開発したいものは、「API Gateway - Lambda - DynamoDB」で構成されるWebサービスとします。

正直なところ、対象像を少し絞らないと選択肢が多すぎて好みの問題になりそうなので・・・

## 注意
調査用のメモです。

実際に全ての選択肢で開発をしてみたわけではなく、入門記事やドキュメントを少しみた程度で判断しています。

そのため正確性に欠ける内容となっている可能性が高いことをご了承ください。

## 共通点

開発ツールで対応していない部分についてのデプロイについては、**AWS CLI**で対応していくことになるでしょう。

## LocalStack

モックサービスの対応数にまず驚いた。

<https://github.com/localstack/localstack>

**LocalStack** はローカルでAWSのサービスのモックを動かしてしまうというツールです。
DockerコンテナでAWS各種サービスを一気に立ち上げることができるので、ローカル環境で開発を完結させることが出来ます。

これ自体にはAWSを管理する機能はなく、Lambdaをローカル環境で開発してテストするときに、ローカルで同時にAPI Gateway + DynamoDBを動かしたいという場合に必要となりそうです。
DynamoDB自身はAmazonからDynamoDB Localが提供されているので、どちらを使うかは検証が必要でしょう。

* API Gateway at http://localhost:4567
* Kinesis at http://localhost:4568
* DynamoDB at http://localhost:4569
* DynamoDB Streams at http://localhost:4570
* Elasticsearch at http://localhost:4571
* S3 at http://localhost:4572
* Firehose at http://localhost:4573
* Lambda at http://localhost:4574
* SNS at http://localhost:4575
* SQS at http://localhost:4576
* Redshift at http://localhost:4577
* ES (Elasticsearch Service) at http://localhost:4578
* SES at http://localhost:4579
* Route53 at http://localhost:4580
* CloudFormation at http://localhost:4581
* CloudWatch at http://localhost:4582
* SSM at http://localhost:4583

起動コマンドも簡単で、一発で全て立ち上げることが出来ます。

```
docker-compose up
```

macの場合は、$TMPDIRにシンボリックリンクがある場合、少しコマンドを変える必要があるようです。

```
TMPDIR=/private$TMPDIR docker-compose up
```

## DynamoDB Local

ローカル開発用のDynamoDB。
ほとんどのLambda開発ツールがAPI Gatewayもサポートしていることから、DynamoDBを接続するローカル環境ではLocalStackよりはこちらを使用することになるのではないかと。公式提供でもあるし。

ダウンロードとインストールガイドは[こちら](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.html)

## aws-sam-local

**SAM** は Serverless Application Modelのことで、aws-sam-localはAmazon公式がサポートしているローカル開発環境です。今はまだbetaですが、近いうちに良くなりそうです。

<https://github.com/awslabs/aws-sam-local>

AWS Blogで利用例が紹介されていて、DynamoDB Localを使う場合についても少し触れられています。
<https://aws.amazon.com/jp/blogs/news/new-aws-sam-local-beta-build-and-test-serverless-applications-locally/>

作成したLambda FunctionをローカルDockerコンテナで実行したり、現時点ではPythonとNode.jsはデバッグ出来るようです。(自分で試したところ、上手くいかなかった)

また、Lambda関数を単純に実行するだけではなく、ローカルのAPI Gatewayを通して実行を確認できます。

PostManで簡単にAPIの動作検証が行えたり、実際のHTTPアクセスの形でLambda関数の検証がローカルで行えます。
また、実行時間やメモリ消費量が表示されるため、AWSにデプロイする前に関数の効率化が出来ます。

ローカルの実行環境がDockerで構築されていて、AWSと同一のNodeバージョンを使用できるため、この点はserverless-offlineプラグインの構成に比べ良い点だと思います。

## Serverless Framework 

現状で一番正解に近いと思います。
Go言語への対応も素早くしてくれました。

<https://github.com/serverless/serverless>

[こちらのQiita記事](https://qiita.com/noralife/items/e36621ddd0e5b8ff4447)や[こっちのQiita記事](https://qiita.com/horike37/items/b295a91908fcfd4033a2)が参考になりそうです。
DynamoDB Localと連携するためのプラグインが存在し、serverless.ymlファイルにAWS上での構成を記載していき、そのままAWSにデプロイ出来るようです。

残念な点は、serverless-offlineプラグインで用意できるローカル実行環境は、ローカルのNodeバージョンになってしまうようです・・・


## Apex

Go言語でLambdaが書ける！！！

純粋にLambdaの開発だけで見ればとても良さそうです。
ただし、ローカル実行はサポートしておらず、AWSリソースの操作もLambdaに限定されています。
その辺りは、[Terraform](https://www.terraform.io/)で補う考えのようです。

[公式](http://apex.run/)

<https://github.com/apex/apex>

### 2018/03/15追記
Serverless FrameworkがGo言語に対応したこともあり、
選択肢としては非常に弱い。

## chalice

Python用のマイクロサービスフレームワークです。

<https://github.com/aws/chalice>

次の様なコードで、APIを定義できます。

```python:chalice
@app.route('/resource/{value}', methods=['PUT'])
def put_test(value):
    return {"value": value}
```

デプロイでAPI Gateway, Lambdaに反映されるため、コードの見通しが良くなりそうです。
IAM Rolesなどは自動生成される様なので、とにかく簡単にコードを書いて、すぐデプロイということが出来そうです。

インストールからコード記述、デプロイまでの操作がHelloworldならこんなに簡単に出来るようです。

```
$ pip install chalice
$ chalice new-project helloworld && cd helloworld
$ cat app.py

from chalice import Chalice

app = Chalice(app_name="helloworld")

@app.route("/")
def index():
    return {"hello": "world"}

$ chalice deploy
...
https://endpoint/dev

$ curl https://endpoint/api
{"hello": "world"}
```

## Zappa

こちらも、とにかく簡単にPythonで作成した関数をAWSにデプロイ出来ることがウリのようです。

<https://github.com/Miserlou/Zappa>

gifアニメーションで実演が付いています。(README.mdから引用しました)
[README.md](https://github.com/Miserlou/Zappa#about)
<p align="center">
  <img src="http://i.imgur.com/f1PJxCQ.gif" alt="Zappa Demo Gif"/>
</p>

REST APIを作成する以外にも、AWS Eventsに対応するものや、Asynchronous Task Executionといって、別のLamdba関数を非同期に呼び出すことが出来る機能を持っているようです。
というか、chaliceに比べると非常に多彩。

また、ZappaはWSGI(Web Server Gateway Interface)をサポートしているので、他のアプリケーションサーバーにデプロイすることも可能です。

## chalice vs Zappa

[こちら](https://blog.zappa.io/posts/comparison-zappa-verus-chalice)に比較記事がありました。