serverless framworkでLambda+APIGatewayをdeployする


はじめに

アプリケーションを Lambda にデプロイする際どんな方法を使用しているだろうか?
AWS SUM ,code deploy と使用してきたがコマンドを複数回叩かないといけなかったりとちょっと面倒臭かった。
そこで最近自分の周りで話題になっている serverless framwork を試してみる。
何やらコマンド一つでビルド・デプロイを行ってくれたりとかなり便利らしい。

Serverless Framework インストール

以下のコマンドを実行し Serverless Framework をインストールする。

$ npm install -g serverless

ローカル端末で Serverless Framework を利用する場合は別途 Credentials の設定が必要になる。

サービス作成

Serverless Framework のサービスを作成する。
今回はcreate-stock-price-indexというサービス名で、Python 3.6の Lambda ファンクションを作成する。

$ serverless create --template aws-python3 --path create-stock-price-index

create-stock-price-indexディレクトリ配下に以下のファイルが作成される。

  • serverless.yml
  • handler.py

今回の deploy ではhandler.pyこちらで作成したコードapp.pyに置き換える。
あわせて、serverless.ymlも以下のように変更しておく。

serverless.yml
service: create-stock-price-index

provider:
  name: aws
  runtime: python3.7
  region: ap-northeast-1

functions:
  get-policy-number-list:
    handler: app.lambda_handler

外部モジュールのインストール

いざ deploy と行きたいところだが、app.pyは以下のように標準で同梱されている以外の外部モジュールを使用している。

app.py
import requests
from bs4 import BeautifulSoup
import yaml

この外部モジュールの管理について今回は UnitedIncome/serverless-python-requirements いう Serverless Framework のプラグインを使用する。
まず、プラグインをインストールする。
Serverless Framework で管理しているディレクトリ上で以下のコマンドを実行する。

$ npm install --save serverless-python-requirements

続いて、serverless.ymlに plugins を追加する。
plugins プロパティで利用するプラグインを指定する。

serverless.yml
service: create-stock-price-index

provider:
  name: aws
  runtime: python3.7
  region: ap-northeast-1

plugins:
  - serverless-python-requirements

functions:
  get-policy-number-list:
    handler: app.lambda_handler

最後に、requirements.txtを用意する。
requirements.txtには import する外部モジュールとその依存関係を記載する。

requirements.txt
beautifulsoup4==4.8.2
certifi==2019.11.28
chardet==3.0.4
idna==2.8
PyYAML==5.3
requests==2.22.0
soupsieve==1.9.5
urllib3==1.25.7

デプロイ

前項まででデプロイの準備が整ったのでいよいよデプロイを実行していく。
create-stock-price-indexディレクトリに移動し、デプロイコマンドを実行する。

$ sls deploy -v

ここで pip と setuptools のバージョンが古いとエラーが出たのでアップデートする。
すると、 CloudFormation により必要なリソースを作成し、 Lambda ファンクションがデプロイされた事が確認できる。

デプロイした Lambda を実行してみる。


$ sls invoke -f get-policy-number-list
{
    "投資指標": [
        {
            "証券コード": 3242,
            "予想PER": "7.77倍",
            "予想EPS": "46.2",
            "実績PBR": "1.08倍",
            "実績BPS": "332.15",
            "予想配当利": "6.69%"
        },
        {
            "証券コード": 9904,
            "予想PER": "15.88倍",
            "予想EPS": "22.1",
            "実績PBR": "1.79倍",
            "実績BPS": "196.51",
            "予想配当利": "5.68%"
        }
    ]
}

問題なく実行でき、期待通りの結果を得る事ができた。

API Gateway 作成

API Gateway を構築することでエンドポイントに対する Get リクエストをトリガーに Lambda を実行することができる。
serverless.ymlに Lambda ファンクションを呼び出すためのイベントを定義する。

serverless.yml
service: create-stock-price-index

provider:
  name: aws
  runtime: python3.7
  region: ap-northeast-1

plugins:
  - serverless-python-requirements

functions:
  get-policy-number-list:
    handler: app.lambda_handler
    events:
      - http:
          path: /
          method: get
          integration: lambda
          request:
            template:
              application/json: '{ "user_id" : "$input.params("password")" }'

デプロイコマンドを実行する。

api keys:
  None
endpoints:
  GET - https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/
functions:
  get-policy-number-list: create-stock-price-index-dev-get-policy-number-list
layers:
  None

デプロイが完了すると ServiceEndpoint が出力される。
このエンドポイントに対してGetリクエストを送ってみる。

Unicodeが文字化けするのでちょっと細工する。

$ curl -X GET "https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/"  | perl -Xpne 's/\\u([0-9a-fA-F]{4})/chr(hex($1))/eg'
{"投資指標": [{"証券コード": 3242, "予想PER": "7.81倍", "予想EPS": "46.2", "実績PBR": "1.09倍", "実績BPS": "332.15", "予想配当利": "6.65%"}, {"証券コード": 9904, "予想PER": "16.02倍", "予想EPS": "22.1", "実績PBR": "1.8倍", "実績BPS": "196.51", "予想配当利": "5.63%"}]}

期待値通りの結果が出力された。

リソースの削除

一通り確認が終わったらAWS上のリソースを削除しておく。

$ sls remove -v

おわりに

簡単なインストールと設定で準備を整える事ができ、その上コマンド一つでデプロイ、スタックの削除と行えるなはかなり便利だった。
パッケージ管理についてもプラグインをインストールするだけでrequirements.txtがそのまま使用できたのも好印象だった。