dehio3’s diary

仕事、生活、趣味のメモ

API Gatewayチュートリアルをserverless frameworkを使って構築してみた

f:id:dehio3:20200207133158p:plain

はじめに

API Gateway + LambdaのREST API環境をserverless frameworkで作成しました。

作成した環境は以下のAPI Gatewayチュートリアルの環境です。

docs.aws.amazon.com

Code

今回環境構築に使用したコードは以下になります。

GitHub - dehio3-org/api-gateway-create-api-as-simple-proxy-for-lambda at v1.0

serverless.yml

serverless.ymlに定義したチュートリアルの各設定項目は以下になります。

service: 
    name: HelloWorld # 今回作成するサービス名を定義

provider:
    name: aws
    region: us-east-1 # 「Hello World」Lambda 関数を作成する-2
    runtime: nodejs12.x # 「Hello World」Lambda 関数を作成する-6.b
    stage: test # API をデプロイしてテストする-3
    apiName: LambdaSimpleProxy # 「Hello, World!」 API を作成する-3.b
    endpointType: REGIONAL # 「Hello, World!」 API を作成する-3.b

functions:
    GetStartedLambdaProxyIntegration:
      handler: index.handler # 「Hello World」Lambda 関数を作成する-7(デフォルト値)
      name: GetStartedLambdaProxyIntegration # 「Hello World」Lambda 関数を作成する-6.a
      events:
        - http:
            path: /helloworld # 「Hello, World!」 API を作成する-4.d,4.e
            method: any # 「Hello, World!」 API を作成する-5.c
            integration: lambda-proxy  #「Hello, World!」 API を作成する-5.d,5.e

package:
  exclude:
    - '**'
  include:
    - 'index.js' # 「Hello World」Lambda 関数を作成する-7 (ローカルに関数コードファイルを作成)

今回はチュートリアルに従い最小限の設定でしたが、メモリサイズやタイムアウトなど他の設定値についても指定可能です。

www.serverless.com

Deploy

serverless frameworkをインストールします。

❯ yarn install

作成したserverless.ymlに従いリソースを作成します。

❯ yarn deploy    
yarn run v1.22.4
$ serverless 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 HelloWorld.zip file to S3 (823 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
..............................
Serverless: Stack update finished...
Service Information
service: HelloWorld
stage: test
region: us-east-1
stack: HelloWorld-test
resources: 11
api keys:
  None
endpoints:
  ANY - https://3rxvyvg3t3.execute-api.us-east-1.amazonaws.com/test/helloworld
functions:
  GetStartedLambdaProxyIntegration: GetStartedLambdaProxyIntegration
layers:
  None
✨  Done in 127.69s.

Test

デプロイ結果よりエンドポイントのURLが確認できるので、チュートリアルに従いリクエストを送信します。

endpoints:
ANY - https://3rxvyvg3t3.execute-api.us-east-1.amazonaws.com/test/helloworld

curl -s -X POST "https://3rxvyvg3t3.execute-api.us-east-1.amazonaws.com/test/helloworld?name=John&city=Seattle" -H "content-type: application/json" -H "day: Thursday" -d "{ \"time\": \"evening\" }" | jq

正しくレスポンスが返ってきました!

{
  "message": "Good evening, John of Seattle. Happy Thursday!",
  "input": {
    "resource": "/helloworld",
    "path": "/helloworld",
    "httpMethod": "POST",

~中略~

    },
    "queryStringParameters": {
      "city": "Seattle",
      "name": "John"
    },
    "multiValueQueryStringParameters": {
      "city": [
        "Seattle"
      ],
      "name": [
        "John"
      ]
    },

~中略~

    "body": "{ \"time\": \"evening\" }",
    "isBase64Encoded": false
  }
}

serverless framework の用に作成されるリソース

serverless frameworkを利用してリソースの作成を行う場合、serverless.ymlに定義していないいくつかのリソースが作成されます。

IAM Role

チュートリアルの「「Hello World」Lambda 関数を作成する-6.d」にて作成していたLambda用のロールが自動で作成されます。

f:id:dehio3:20200708001602p:plain

serverless.yml内で個別のポリシーを指定していない場合は、以下のログ出力の為のポリシーがデフォルトで適用されます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:CreateLogStream",
                "logs:CreateLogGroup"
            ],
            "Resource": [
                "arn:aws:logs:us-east-1:<acount id>:log-group:/aws/lambda/GetStartedLambdaProxyIntegration:*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:us-east-1:<acount id>:log-group:/aws/lambda/GetStartedLambdaProxyIntegration:*:*"
            ],
            "Effect": "Allow"
        }
    ]
}

S3

lambdaのコードとCloudFormationのテンプレートを保存するバケットが自動で作成されます。

f:id:dehio3:20200708002210p:plain

デプロイ毎に日時のパスが作成されファイルが管理されます。

f:id:dehio3:20200708002407p:plain

packageコマンドを使う事で、アップロードされるパッケージを事前に確認する事もできます。

❯ yarn run package
yarn run v1.22.4
$ serverless package
Serverless: Packaging service...
Serverless: Excluding development dependencies...
✨  Done in 9.98s.

❯ ls -ltr .serverless     
total 72
-rw-r--r--  1 tomohide  staff   1653  7  8 00:27 cloudformation-template-create-stack.json
-rw-r--r--  1 tomohide  staff    823  7  8 00:27 HelloWorld.zip
-rw-r--r--  1 tomohide  staff   8721  7  8 00:27 cloudformation-template-update-stack.json
-rw-r--r--  1 tomohide  staff  14279  7  8 00:27 serverless-state.json

❯ tar tvf .serverless/HelloWorld.zip 
-rw-r--r--  0 0      0        1745  1  1  1980 index.js

serverless.yml内のpackageにて、アップロードするパッケージを意図的に指定しなかった場合は、カレントに存在する全てのファイルを関数コードファイルとしてアップロードします。

関数コードファイルのサイズが大きくなりすぎて、Lambdaコンソール画面にて関数コードファイルが展開されず中身が確認できない場合などに便利です。

Cloud Formation

serverless frameworkはCloudFormationにてserverless.ymlに定義したAWSリソースを作成している為、スタックが作成されます。

f:id:dehio3:20200708003807p:plain

まとめ

雰囲気で使ってたserverless frameworkを把握する為、チュートリアルベースで設定方法を再確認してみました。

S3やCloud Formationなどは、serverless.ymlからは確認できないので、仕組みを知らずに触っていると把握しにくい内容かもしれません。

また、各リソース名はservice.name+stageとなるので、それぞれの値を設定する時は意識して設定する必要がありそうです。

今回はチュートリアル内容をそのまま構築しましたが、次回以降でカスタムドメインの設定や、GitHubActionsでの自動デプロイなども試してみたいと思います。