Serverless FrameworkのVersion1.0 RC1版を試してみる(Lambda編)


# 初めに
最近、仕事でLambda Functionを使用する機会があったのですが、
AWSのマネジメントコンソール上でコードを修正、もしくはzipファイルでコードをアップロードしたりするのが
面倒だなと思っていたら、便利そうなのがあったので興味本位で試してみることにしました。

# Lambda functionのデプロイと実行まで

## インストール

### Node.js

Node.jsのv4以上が必要。まずはNode.jsをインストール。
 今回は、LTSだったv4.5.0をインストール。

```bash
$ brew install nodebrew
$ nodebrew
nodebrew 0.9.6
$ nodebrew install-binary v4.5.0
Fetching: https://nodejs.org/dist/v4.5.0/node-v4.5.0-darwin-x64.tar.gz
######################################################################## 100.0%
Installed successfully
$ nodebrew use v4.5.0
use v4.5.0
```

### Serverless

RC版が出たようなので、そちらをインストールすることにします。

```bash
$ npm install -g serverless@beta
$ serverless version
1.0.0-rc.1
```

### awscli

あらかじめAWSコンソールのIAMよりテストで使用するユーザを作成しておいてください。

公式のドキュメントには「AdministratorAccess」権限を付与してねとあるのですが、
さすがにヤダなーということで、テストも兼ねて、ユーザにAttachするポリシーは、「PowerUserAccess」権限にしてみます。

本番環境では適切なポリシーでやるべきなのでご注意ください。

```bash
$ brew install pyenv
```

```bash:~/.bash_profile
$ export PYENV_ROOT="$HOME/.pyenv"
$ export PATH="$PYENV_ROOT/bin:$PATH"
$ eval "$(pyenv init -)"
```


```bash
$ pyenv install 3.5.1

# 上記でエラーになるようであれば、下記を実行後、再度インストール
$ xcode-select --install
$ pyenv install 3.5.1
$ pyenv global 3.5.1
$ pyenv versions
  system
* 3.5.1
$ pip install -U pip

# awscliインストール
$ sudo pip install awscli

# awscliアップデート
$ pip install -U awscli

$ aws --version
aws-cli/1.10.65 Python/3.5.1 Darwin/15.6.0 botocore/1.4.55

$ aws configure
AWS Access Key ID [********************]:
AWS Secret Access Key [********************]:
Default region name [ap-northeast-1]:
Default output format [json]:
```
 
## プロジェクト作成〜デプロイ〜実行

templateには下記が利用可能です。
- aws-nodejs
- aws-python
- aws-java-maven
- aws-java-gradle

今回はpythonを利用してみます。

```bash
$ serverless create --template aws-python --path my-service
Serverless: Creating new Serverless service...
Serverless: Creating the service in "/Users/tsuyoshi/Documents/src/my-service"
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v1.0.0-rc.1
 -------'

Serverless: Successfully created service with template: "aws-python"
$ cd my-service
$ ls
event.json     	handler.py     	serverless.yml
```

作成されるファイルも3つで、1.0のbeta版の頃よりもさらにシンプルになっています。

公式ドキュメント読むと、「stage」と「region」をデフォルトから変更したいなら、deployの前にserverless.ymlを変更してねとあります。

```bash:serverless.yml
provider:
  name: aws
  region: ap-northeast-1
```

今回はregionを「ap-northeast-1」にしたいので、ドキュメント通りprovider内にregionのみを追加しています。
（これ、default部分がコメントアウトされてるけど、beta版の頃の残骸なのかな。。。）

早速deploy。

```bash
$ serverless deploy
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading service .zip file to S3...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.......Serverless: Deployment failed!

  Serverless Error ---------------------------------------

     An error occurred while provisioning your stack: IamRoleLambdaExecution
     - API: iam:CreateRole User: arn:aws:iam::XXXXXXXXXXXX:user/XXX
     is not authorized to perform: iam:CreateRole on resource:
     arn:aws:iam::XXXXXXX:role/my-service-dev-IamRoleLambdaExecution-XXXXXX.

  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
```

権限が無いということでエラーに。
これ以上、権限設定に時間を割くことはしたくないので、一旦「AdministratorAccess」権限に変更して再チャレンジ。

```bash
$ serverless deploy
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading service .zip file to S3...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.........
Serverless: Stack update finished...

Service Information
service: my-service
stage: dev
region: ap-northeast-1
endpoints:
  None
functions:
  my-service-dev-hello: arn:aws:lambda:ap-northeast-1:068422550899:function:my-service-dev-hello
```

問題なくAWSのLambda上にデプロイされたようです。
（deploy時のデフォルトのstageは「dev」なので、lambdaのfunction名に「-dev-」が付与されるみたいです）

AWSコンソールからIAMとLambdaを見てみると、登録されていることが確認できます。

- IAM ロール
![スクリーンショット 2016-09-13 8.53.40.png](https://qiita-image-store.s3.amazonaws.com/0/71316/ecafda0c-eefb-2402-353b-ff70e1f16fb6.png "スクリーンショット 2016-09-13 8.53.40.png")
- Lambda Functions
![スクリーンショット 2016-09-13 8.53.13.png](https://qiita-image-store.s3.amazonaws.com/0/71316/3d8b536c-7e8a-7c63-fd5e-61a3430b47de.png "スクリーンショット 2016-09-13 8.53.13.png")


早速実行してみましょう

```bash
$ serverless invoke --function hello
{
    "message": "Go Serverless v1.0! Your function executed successfully!",
    "event": {}
}
```

無事実行できたようです。

CloudWatch Logs側にもログが残っていました。
![スクリーンショット 2016-09-13 8.52.45.png](https://qiita-image-store.s3.amazonaws.com/0/71316/27b4e895-6445-e1ab-cc03-aa8a0cc00782.png "スクリーンショット 2016-09-13 8.52.45.png")

## 所感
ローカルで軽く動作確認をしつつ、AWS上へデプロイが簡単に出来る点については、やはり便利だと感じました。
ただ、業務上で使用するには、細かくIAMで権限を設定してあげる必要がありそうで苦労しそうです

deployやinvoke時のそれぞれオプションを見てみたのですが、Lambdaの「バージョン」や「エイリアス」を指定したり、変更したりすることは出来ず、
あくまでも、stage（function）毎の最新（$LATEST）を対象にするようです。

この辺りは、最新版はどんどん更新できるようにしておくから、
バージョンニングやエイリアスの設定は、必要な時にAWSコンソール上から行ってねってことなのな？
旧バージョン実行したいとかありそうな気もするけど。。。

この辺り「API Gateway」とセットで使用するとより詳しく理解できるのかも。