AWS Lambda入門①(Node編)〜関数をデプロイして動かす〜

## 概要

- ServerlessFrameworkを使ってLambda関数を作り、ローカルで動作確認したあとにAWSにデプロイしてアクセスするところまでやってみます

## Lambdaとは

- LambdaはAWSが提供するサービスの1つで以下のような特徴を持ちます

### サーバーレス

- 通常のアプリケーションはサーバにデプロイし稼働させることでアクセスすることができますが、当然サーバが止まっていたら利用することはできません
- Lambdaはサーバーレスに分類されるサービスで、アクセスがあるとそのつど起動し処理が実行され終了すると停止します
- つまりLambdaはサーバの死活監視のようなことをする必要がなく、また課金も実行時間単位なので金銭面でもお得といった特徴があります

### FaaS

- LambdaはいわゆるFaaS(Function as a Service)に分類されます
- つまり、Function(関数)をデプロイして、それを公開するサービスというわけですね

## Lambda関数の作成

### 関数の作成

- 今回は[ServerlessFramework](https://serverless.com/)を使います

#### ServerlessFrameworkのインストール

- グローバルにインストール

```sh
npm i -g serverless
```

- 動作確認

```sh
sls -v
```

> ServerlessFrameworkのコマンドが`sls`と`serverless`のどちらでも動きます

- 以下のような内容が表示されればOKです

```sh
Framework Core: 1.64.1
Plugin: 3.4.1
SDK: 2.3.0
Components Core: 1.1.2
Components CLI: 1.4.0
```

#### 雛形の生成

- ServerlessFrameworkの機能でLambda用の関数や設定ファイルの雛形を生成します
    - 今回は`aws-nodejs`というtemplateを指定します
    - 他にどんなtemplateがあるかは`serverless create --help`を実行すると見ることができます

```sh
mkdir sls-sample
cd sls-sample
serverless create --template aws-nodejs
```

- 以下のようなファイルが生成されているはずです

```
% tree -a
.
├── .gitignore
├── handler.js
└── serverless.yml
```

- `handler.js`は今回のメインのファイルでLambdaで実行する処理を書きます
- `serverless.yml`はServerlessFrameworkを使う上での設定ファイルです
- `.gitignore`はgit管理する際にServerlessFrameworkが生成する一時ファイルを管理対象外にするための記載が追加されています

### 関数をローカルで実行してみる

- AWSにデプロイする前にまずはローカルで動作確認します

#### 関数の内容を確認

- 実行する前に`handler.js`の中身を確認しましょう

```js
'use strict';

module.exports.hello = async event => {
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: 'Go Serverless v1.0! Your function executed successfully!',
        input: event,
      },
      null,
      2
    ),
  };

  // 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 };
};
```

- メインの処理である関数を`hello`という名前で`module.exports`によって外部からアクセス可能にしています
- 関数の中を見てみると`return`文しかありません
- `statusCode`と`body`の2つのプロパティを持ったobjectを返却しています
    - `statusCode`は実行結果を表現していて`200`は成功を意味しています(詳しくはググって)
    - `body`は実行結果のメイン部分でメッセージを定義した`message`と入力値をそのまま返却する`input`を返しています

#### ローカルで実行する

- それでは実行してみましょう
- ServerlessFrameworkを使うとAWSにデプロイせずともLocalマシン上で動作確認ができます

```sh
sls invoke local --function hello
```

- `sls invoke`が関数を呼び出すためのコマンドです
    - そのあとの`local`はAWSにアクセスするのではなく手元のファイルにアクセスすることを意味しています
    - 最後の`--function hello`は実行したい関数を指定していています
        - 先程`hello`という名前でexportしていることを確認しましたね
- 実行結果はこんな感じです

```sh
{
    "statusCode": 200,
    "body": "{\n  \"message\": \"Go Serverless v1.0! Your function executed successfully!\",\n  \"input\": \"\"\n}"
}
```

- `input`が空っぽなので適当な値を渡してみます
    - `--data`で値を渡すことができます

```sh
sls invoke local --function hello --data Hello
```

```sh
{
    "statusCode": 200,
    "body": "{\n  \"message\": \"Go Serverless v1.0! Your function executed successfully!\",\n  \"input\": \"Hello\"\n}"
}
```

- Helloも取得できることが確認できました

### 関数をAWSにデプロイして実行してみる

- AWSにデプロイしてアクセスしてみます

#### AWSにアクセスするための設定

- AWSにデプロイするためにはキー情報の設定が必要になります
- アクセスキーの発行については[IAM ユーザーのアクセスキーの管理](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey)を参考に実施してください
- 以下のコマンドの`aws_access_key_id`にAccess key IDを、`aws_secret_access_key`にSecret access keyを入れて実行してください
    - `~/.aws/credentials`がすでに作成されている場合は上書きされるか尋ねられるので問題ないかファイルの内容を確認し対応してください

```sh
serverless config credentials --provider aws --key aws_access_key_id --secret aws_secret_access_key
```

- **キー情報が漏洩し悪用されると多額の請求につながる危険性があるので取り扱いには十分気をつけてください**

#### デプロイする

- デプロイもServerlessFrameworkの機能で簡単に実行できます

```sh
serverless deploy --region ap-northeast-1
```

- `--region ap-northeast-1`はAWSの東京リージョンにデプロイすることを指定しています
    - `serverless.yml`に記載しておけば毎回引数で設定する必要はなくなります

```yml:serverless.yml
# 抜粋
provider:
  name: aws
  runtime: nodejs12.x
  region: ap-northeast-1 # これ
```

- デプロイが成功すると以下のような出力がされます

```sh
Service Information
service: sls-sample
stage: dev
region: ap-northeast-1
stack: sls-sample-dev
resources: 6
api keys:
  None
endpoints:
  None
functions:
  hello: sls-sample-dev-hello
layers:
  None
Serverless: Run the "serverless" command to setup monitoring, troubleshooting and testing.
```

- エラーが出た場合は出力されたログをよく確認して対処しましょう

#### デプロイした関数を実行する

- AWSにデプロイしたLambda関数もコマンドラインから実行することができます

```
sls invoke --function hello --data Hello --region ap-northeast-1
```

- ローカルで実行したときとの違いは`local`を指定していないだけですね
- ローカルのときと同じように以下のレスポンスを受け取れていれば成功です

```
{
    "statusCode": 200,
    "body": "{\n  \"message\": \"Go Serverless v1.0! Your function executed successfully!\",\n  \"input\": \"Hello\"\n}"
}
```

## まとめ

- Lambda関数の基本的な扱い方について紹介しました
- ServerlessFrameworkを使うと設定やデプロイ周りがとても簡単ですね！