serverlessでCLIからlambdaをデプロイする

# 概要
`AWS`の`lambda`は`AWS Management Console`内で直接書くこともできますが、
`git`でソースコードを管理して、CLIからデプロイしたいと思うことはありませんか？

当記事では[Serverless](https://serverless.com/)を使って
`Node.js`で実装したサンプルを`lambda`にデプロイする手順の例を示します。

筆者がCLIでのAWS操作にあまりなれていなかったのもあり、本記事では`AWS Management Console`での操作手順もやや掘り下げて記載していますが、
`Serverless`の基本機能はServerlessのメンテナでもある@horike37さんの下記の記事により詳しくまとまっているので、そちらを参照いただくのが良いと思いました。
[Serverless Frameworkの使い方まとめ](https://qiita.com/horike37/items/b295a91908fcfd4033a2)


# awscliのインストール
```sh
$ brew install awscli
```

# デプロイユーザーのアクセスキーの取得
デプロイに利用するアカウントでawscliでログインするために、`AWS Management Console`でユーザーの認証情報を取得します。

1. `IAM`->`Users` -> `デプロイに使うユーザー` -> `Security credentials` -> `Create access key`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139673/e0487c3a-bc88-cfa8-c426-39116f41b506.png)
2. `Access key ID` と `Secret access key` を保管する。（`Download .csv file`でCSVをダウンロードしておくのが良いでしょう。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139673/b35b4eed-ae6c-3c5e-810b-52303cddb436.png)

# デプロイユーザーへの権限付与
serverlessでlambdaをデプロイするには、デプロイユーザーにデプロイ用の権限が必要です。
ここでは、ポリシーの設定手順の例を示します。

1. `IAM`->`Policies`->`Create policy` をクリック ->`JSON` タブをクリック
2. 下記を貼り付け

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "iam:*",
                "apigateway:*",
                "s3:*",
                "logs:*",
                "lambda:*",
                "cloudformation:*"
            ],
            "Resource": "*"
        }
    ]
}
```
※`Action`や`Resource`は、セキュリティの観点からは必要なポリシーやリソースをもっと限定的に指定するのが好ましいですが、数が多くて細部の洗い出しが大変だったため、ワイルドカードでざっくりと指定をしました。
3. ポリシー名は任意ですが、ここでは例として`lambdaDeployPolicy`としてポリシーを作成します。
4. `IAM` -> `Users` -> デプロイユーザーを選択 -> `Add permissions` -> `Attach existing policies directly`
5. `3.`で作成した`lambdaDeployPolicy`を選択し、`Next: Review` -> `Add permissions` でポリシーを追加

# awscliにデプロイユーザーとしてログイン
```console
$ aws configure
AWS Access Key ID [None]: <Access key IDを貼り付け>
AWS Secret Access Key [None]: <Secret access key> を貼り付け
Default region name [None]: ap-northeast1
Default output format [None]: <そのままエンター>
```

# serverlessのインストール
```sh
$ npm i -g serverless
```

# serverlessプロジェクトの生成
```sh
$ sls create --template aws-nodejs --path lambda-deploy-serverless
$ cd lambda-deploy-serverless
```

# serverlessの設定ファイルを更新
デフォルトだとリージョンが`us-east1`になっていたり、APIゲートウェイの設定は含まれていないので、下記のように指定を加えます

```yml:serverless.yml(更新)
service: lambda-deploy-serverless
provider:
  name: aws
  runtime: nodejs8.10
  stage: dev
  region: ap-northeast-1 # ap-northeast-1リージョンにデプロイする
functions:
  hello: # 関数名の指定
    handler: handler.hello
    events:
      - http: # API Gatewayの指定
          path: hello
          method: get
```

その他の設定はこちらのリファレンスを参照: 
https://serverless.com/framework/docs/providers/aws/guide/serverless.yml/


# デプロイ
```sh
$ sls deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service lambda-deploy-serverless.zip file to S3 (45.3 KB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
........................
Serverless: Stack update finished...
Service Information
service: lambda-deploy-serverless
stage: dev
region: ap-northeast-1
stack: lambda-deploy-serverless-dev
resources: 10
api keys:
  None
endpoints:
  GET - https://**********.execute-api.ap-northeast-1.amazonaws.com/dev/hello
functions:
  hello: lambda-deploy-serverless-dev-hello
layers:
  None
```

このようにLambdaがデプロイされていれば成功です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139673/02a10e9c-caf3-99e9-6662-c79f605c2970.png)

もしもエラーになる場合は、ログのエラー箇所を参照して、ポリシーが適切に設定されているか確認して下さい。

詳細ログを標準出力に出力させるには、下記のようにします

```sh
SLS_DEBUG=* serverless deploy
```