LoginSignup
6
6

More than 3 years have passed since last update.

AWS LambdaでPython3のfunctionをServerless FrameworkでDeploy

Last updated at Posted at 2019-12-17

※ 公開日を勘違いしていて、翌日になってしまってスミマセン

はじめに

前提

  • npmコマンドが使える状態
  • serverless framework用のIAMユーザがある状態
    • 公式のこの辺を参考にするとよいです(AdministratorAccessが推奨)
  • dockerが使える状態

Serverless Frameworkの導入と設定

導入はnpm install一発です。

$ npm install serverless

--versionでpathが通っていることを確認します。

$ serverless --version
Framework Core: 1.59.3
Plugin: 3.2.5
SDK: 2.2.1
Components Core: 1.1.2
Components CLI: 1.4.0

事前に作っておいた、Serverless Framewrok用のIAMアカウントを、serverless config credentialsで設定します。

serverless config credentials --provider aws --key foo --secret bar

これで事前準備は終わりました。

テンプレートの生成とdeploy

Python3用のテンプレートプロジェクトを生成します。

serverless create --template aws-python3 --name aws-lambda-hello-python --path aws-lambda-hello-python

実際にファイルとしては以下のようなものが生成されます。

$ cd aws-lambda-hello-python

$ tree
.
├── handler.py
└── serverless.yml

0 directories, 2 files

上記コマンドでは、mainメソッドは生成されませんが、今回はlocalでも動作させたいと思ったので、追記しています。

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
    }
    """

if __name__  == "__main__":
    print(json.dumps(hello("","")))

コメントが多数書かれていますが、最低限必要なのは以下のみです(リージョンを指定していないので、defaultのus-east-1にデプロイされます)

serverless.yml
service: aws-lambda-hello-python

provider:
  name: aws
  runtime: python3.8

functions:
  hello:
    handler: handler.hello

Localで少し動かしてみます。

$ pyenv local 3.8.0
$ python3 handler.py
{"statusCode": 200, "body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": \"\"}"}

動きました。では、deployして動作確認してみます。

$ serverless deploy -v
(メッセージ省略)

$ serverless invoke -f hello
{
    "statusCode": 200,
    "body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {}}"
}

ちゃんとデプロイできたようです。

外部ライブラリの利用

  • 外部ライブラリを使えるようにしたいと思います。
  • numpyを導入したいのですが、nativeのライブラリは環境別にビルドが必要で、普通にLambdaで使うときは少々面倒ですが、Serverless Frameworkを使うと比較的楽になります。

venv環境を使えるようにして、numpyをinstallし、freezeします。

$ python3 -m venv .venv
$ .venv/bin/pip install numpy
$ .venv/bin/pip freeze > requirements.txt

適当にnumpyを使う処理を追記します。(meanがかえるようになります)。

handler.py
import json
import numpy as np


def hello(event, context):
    arr = range(1, 100+1)
    mean = np.mean(arr)

    body = {
        "message": "Go Serverless v1.0! Your function executed successfully!",
        "input": event,
        "mean" : mean
    }

    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
    }
    """

if __name__  == "__main__":
    print(json.dumps(hello("","")))

localで実行するとこんな感じです。

$ .venv/bin/python3 handler.py
{"statusCode": 200, "body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": \"\", \"mean\": 50.5}"}

serverlessでrequirementsを使えるようにするプラグインをinstallします。

npm install serverless-python-requirements

serverless.ymlに追記します(plugins以下を追記)

service: aws-lambda-hello-python

provider:
  name: aws
  runtime: python3.8

functions:
  hello:
    handler: handler.hello

plugins:
  - serverless-python-requirements

custom:
  pythonRequirements:
    dockerizePip: true

package:
  include:
    - handler.py
  exclude:
    - '**'

deployしてみます(dockerでnumpyのビルドが走り、デプロイされます)

$ serverless deploy -v

動作確認してみます。

$ serverless invoke -f hello
{
    "statusCode": 200,
    "body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {}, \"mean\": 50.5}"
}

ちゃんとnumpyが動いていますね!
それでは楽しいPython & Serverless生活を!

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6