Serverless FrameworkでAWS Lambdaをデプロイ

# Serverless Framework

[Serverless Framework](https://serverless.com/)はAWS LambdaやAmazon APIGatewayなどを利用したサーバーレスなアプリケーションを構築や管理・デプロイするためのツールです。
設定ファイルを作成してコマンドを実行することで、LambdaやAPIGatewy、DynamoDB、S3などのAWSサービスを構築・管理することができます。
さらに、作成したプロジェクトをGithubなどに公開することで、Lambda関数のコードの管理を行えることや、他のAWSアカウントでも使用できるためAWS環境の共有を行うこともできます。
開発用のアカウントから、本番用のアカウントへの移行をコマンドで簡単に行うことができます。
今回はServerless Frameworkを用いてAWS Lambdaをデプロイします。

# 環境

npmはNode.jsをインストールした際に同時にインストールされます。Nodeの管理はanyenvを使用しています。
また、AWS コマンドラインインターフェイス（AWS CLI）もインストールします。

[anyenvのndenvを使ってnode.jsのバージョンを管理する](https://qiita.com/0084ken/items/22ca33032773c6d2f9f4)

[AWS CLIのインストール](https://qiita.com/yuyj109/items/3163a84480da4c8f402c)

- OS : macOS High Sierra
- OpenSSL : 2.2.7
- node : 10.5.0
- npm : 6.1.0
- AWS CLI : 1.15.24

# Serverless Frameworkのインストール

slfというディレクトリを作成し、環境を構築します。

```
$ mkdir slf
$ cd slf
$ npm init
$ ls
  package.json
```

依存ライブラリやプロジェクトの基本情報を記述する「package.json」が作成されます。
このjsonファイルを共有することで、他の環境でもnpmを使用して依存ライブラリをインストールすることが可能になります。

```
$ npm install -g serverless
$ serverless --version
  1.30.0
```

`npm install -g serverless`でインストールします。`serverless --version`でバージョンが表示されれば正しくインストールされています。

# AWSアカウントの設定

[公式サイト](https://serverless.com/framework/docs/providers/aws/guide/credentials/)にAWSアカウントのセットアップ方法が書かれています。AWSアカウントが作成されている前提で進めます。

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

`serverless config credentials`コマンドでAWSアカウントの設定を行います。`--provider`で使用するサービス（今回はAWS）を指定します。AWS IAMで作成した認証情報を、`--key`でアクセスキーIDを、`--secret`シークレットアクセスキーを指定します。
`aws configure`で設定した情報を確認することができます。

# Lambda関数の作成

Lambdaのプロジェクトを作成しましす。使用する言語はPython3.6です。

```
$ serverless create --template aws-python3 --name slf-sample
$ ls
handler.py        package-lock.json serverless.yml
node_modules      package.json
```

|ファイル|用途|
|:--|:--|
|event.json|Lambda関数のテストでハンドラー関数の引数eventに渡されるテストデータ|
|handler.py|Lambda関数が呼び出す関数。実際にLambdaの実装を行う。|
|serverless.yml|各種設定ファイル。Lambdaの設定、エンドポイントの設定、リソースの設定、トリガーの設定、などを記述する。|

```python3:handler.py
import json


def hello(event, context):
    body = {
        "message": "Go Serverless v1.0! Your function executed successfully!",
        "input": event
    }

    response = {
        "statusCode": 200,
        "body": json.dumps(body)
    }

    return response

    # Use this code if you don't use the http event with the LAMBDA-PROXY
    # integration
    """
    return {
        "message": "Go Serverless v1.0! Your function executed successfully!",
        "event": event
    }
    """

```

Pythonのファイルには、引数のeventの内容をJSON形式で表示する処理が書かれています。
このLambdaをデプロイしていきます。

# Lambdaのデプロイ

## デプロイ先のリージョンの設定

```:serverless.yml
# you can overwrite defaults here
#  stage: dev
#  region: us-east-1
```

デプロイ先のリージョンはデフォルトで`es-east-1`バージニア北部に指定されているので、`region`キーの値を`ap-northeast-1`で東京に変更する。

```:serverless.yml
# 使用するクラウドサービス(AWS)と言語(Pytho3.6)を指定
provider:
  name: aws
  runtime: python3.6

# ステージを指定。開発と本番環境を切り分けることができます。
  stage: dev
# デプロイするリージョンを指定
  region: ap-northeast-1
```

## IAM Roleの設定
AWSアカウントで作成したIAM RoleをLambdaに設定することができます。
IAM RoleのロールARNを`serverless.yml`の`role`キーに記述します。

```:serverless.yml
# 使用するクラウドサービス(AWS)と言語(Pytho3.6)を指定
provider:
  name: aws
  runtime: python3.6

# ステージを指定。開発と本番環境を切り分けることができます。
  stage: dev
# デプロイするリージョンを指定
  region: ap-northeast-1
# Lambdaに適用するIAM Roleを指定
  role: "your IAM Role ARN"
```

## Lambdaのデプロイ

```
$ serverless deploy -v
```

`serverless deploy -v`でデプロイすることができます。関数単位でデプロイする場合は
`serverless deploy function -f "your lambda function"`で可能です。

<img width="1118" alt="lambda.png" src="https://qiita-image-store.s3.amazonaws.com/0/239179/08bbc339-8505-f012-30fe-29f9b36f7553.png">


図のようにAWSのコンソール画面に、設定ファイルで指定したLambdaが作成されていればデプロイ成功です。

# Lambdaの実行
```
$ serverless invoke -f hello -d '{"test":"test"}'
{
    "statusCode": 200,
    "body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {\"test\": \"test\"}}"
}
```

`serverless invoke`コマンドでLambdaの実行を行えます。
`-f`オプションには実行する関数名を指定できます。`serverless.yml`ファイルのfunctionリソースに設定されている関数名を指定することができます。

```:serverless.yml
# Lambdaを構築
functions:
  # 関数名を指定
  hello:
    # handler関数を指定
    handler: handler.hello
```

event引数にパラメーターを指定する際には、`-d`コマンドで指定します。
出力には`handler.py`の`hello`関数の戻り値が出力されていることが確認できます。

# サービスの削除

```
$ serverless remove
```

デプロイしたサービスをローカルから`serverless remove`コマンドで削除出来ます。

# まとめ
今回はServerless Frameworkの環境構築から、AWS Lambda関数の作成・デプロイ・実行までを行いました。
次回は、Lambda関数のトリガーの設定や、連携サービスの設定などを行いたいと思います。

[Serverless FrameworkでAPIGateway・Lambda・DynamoDBを構築する](https://qiita.com/t_okkan/items/546330b5f4da720c71a7)