【Serverless Framework】Serverlessを試してみた【導入編】

## 概要
なかなか使う機会がないので、ちょっとした登録処理レベルのサンプル作成をしてみます。
まずは基礎の基礎で導入部分から始めて見る。
GitHubは[こちら](https://github.com/mori-hisayuki/serverless_sample)

## 環境
|ツール|ver|
|---|---|
|VSCode|1.26|
|Python|3.6.4|
|node|v10.9.0|
|nodebrew|0.9.8|
|npm|6.4.1|
|Serverless Framework|1.30.3|


## インストール
### nodeのupdate
後半に[これ](https://github.com/serverless/serverless/issues/3723)でハマったので、nodeのバージョンは8.1.0以上にしましょう。
今回はv10.9.0を使用します。

```bash
$ nodebrew install-binary 10.9.0
Fetching: https://nodejs.org/dist/v10.9.0/node-v10.9.0-darwin-x64.tar.gz
######################################################################## 100.0%
Installed successfully
```



### npmのUpdate
npmが6.0.0のままだったので、updateしました。
npmのインストール手順は[こちら](https://qiita.com/Esfahan/items/067fc366d6a6e7b8690d)を参考に

```bash
$ npm update


   ╭────────────────────────────────────────────────────────────────╮
   │                                                                │
   │       New minor version of npm available! 6.0.0 → 6.4.1        │
   │   Changelog: https://github.com/npm/npm/releases/tag/v6.4.1:   │
   │               Run npm install -g npm to update!                │
   │                                                                │
   ╰────────────────────────────────────────────────────────────────╯
$ npm install -g npm
```

### npmの初期化（packge.jsonの作成） 
今回は先にGitHubでリポジトリ作って、作業用ディレクトリは`git clone`でダウンロードした場所にします。
僕の場合はHOME直下にvscodeディレクトリを作り、そこに'git clone'してきています。

```
$ npm init
```

### Serverless Frameworkインストール

```bash
$ npm install --save serverless
```

インストール後にパスを通します。

```bash
$ npm bin sls
$ echo 'export PATH="$HOME/vscode/serverless_sample/node_modules/.bin/:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile
```

パス確認とインストール確認

```bash
$ npm bin sls
/Users/hisayuki/vscode/serverless_sample/node_modules/.bin
$ sls -v
1.30.3
```

## credential登録
以下のコマンドで、AWSのアクセスキー、シークレットアクセスキーを登録。
今回は専用profileにします。defultは他で使うので・・・

```bash
$ sls config credentials --provider aws --key AKIxxxxxxxxxxxx --secret jXsxxxxxxxxxxxxxxxxxxxxxxxx --profile serverless
Serverless: Setting up AWS...
Serverless: Saving your AWS profile in "~/.aws/credentials"...
Serverless: Success! Your AWS access keys were stored under the "serverless" profile.
```

`Serverless: Success!`とでたら完了。
profileも"serverless"となってます。
一応、`cat ~/.aws/credentials`で確認はしました。

## Lambda関数の作成
今回はPytho3でやるので`-t aws-python3`を指定 

```bash
$ sls create -t aws-python3 -p sample-app
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/Users/hisayuki/vscode/serverless_sample/sample_app"
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v1.30.3
 -------'

Serverless: Successfully generated boilerplate for template: "aws-python3"
```

出来上がったディレクトリの中身を確認

```bash
$ ls -la sample-app/
total 24
drwxr-xr-x  5 hisayuki  staff   160  9  4 20:13 .
drwxr-xr-x  9 hisayuki  staff   288  9  4 20:13 ..
-rw-r--r--  1 hisayuki  staff   192  9  4 20:13 .gitignore
-rw-r--r--  1 hisayuki  staff   497  9  4 20:13 handler.py
-rw-r--r--  1 hisayuki  staff  2886  9  4 20:13 serverless.yml
```

## まずdeploy

serverless.ymlにはいろいろ書いてありますが、とりあえず以下の設定だけしてdeploy

```yml:serverless.yml
service: sample-app # NOTE: update this with your service name

# You can pin your service to only deploy with a specific Serverless version
# Check out our docs for more details
# frameworkVersion: "=X.X.X"

provider:
  name: aws
  runtime: python3.6
  timeout: 300
  profile: serverless

# you can overwrite defaults here
  stage: dev
  region: ap-northeast-1
  
functions:
  hello:
    handler: handler.hello
```

```bash
$ sls deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (390 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
...............
Serverless: Stack update finished...
Service Information
service: sample-app
stage: dev
region: ap-northeast-1
stack: sample-app-dev
api keys:
  None
endpoints:
  None
functions:
  hello: sample-app-dev-hello
```

## 出来たLambda関数を実行
invokeコマンドからLambda関数を実行可能

```bash
$ sls invoke -f hello
{
    "statusCode": 200,
    "body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {}}"
}
```

`-d`はパラメータを渡す、`-p`はファイルを渡す

```bash
$ sls invoke -f hello -d '{"key":"test_run"}'
{
    "statusCode": 200,
    "body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {\"key\": \"test_run\"}}"
}
```

```bash
$ sls invoke -f hello -p sample.json
{
    "statusCode": 200,
    "body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {\"key\": \"test_put_file\"}}"
}
```

## 作成したLambda関数を削除
作成したLambda関数を削除。
手動でも消せるけど、作成時に他のリソース作ったりするので（S3のバケットとか)、コマンドから消すこと推奨です。

```bash
$ cd sample-app
$ sls remove -v
```


## まとめ
- なんとなくやりたいなーって思ってたことだったので、ようやく手を付けれたのはよかった。
- ハマったのはnodeのバージョンが8.0.0で、deploy時にエラー吐いたことくらい。
- serverless.ymlはIAMの設定なども書けるけど、今回は全部端折ってとりあえず動くところまで。
- 次はLambda関数を作って、ローカルテストとか出来るところまでやりたい。

## 参考資料
[npmのインストール手順](https://qiita.com/Esfahan/items/067fc366d6a6e7b8690d
)
[AWS Lambda（Python） の開発環境・テスト・デプロイ・CI 考察](https://dev.classmethod.jp/server-side/serverless/aws-lambda-dev-test-deploy-ci/)
[Node.jsの管理をHomebrewからnodebrewに変える](https://qiita.com/takeshi81/items/805f504503cd93151ca6)