#準備
SAM CLIはpythonで実装されているため、先にpythonの環境を設定。
Macのデフォルトはpython 2.7なので、pyenvなどで3.xにしておく。
実行時はDockerを使うので、Docker for macOSをインストールしておく。
さらに、AWS CKUもインストールしておく。
#インストール
pythonで書かれているのでpipでもインストールできるが、OSXならbrewでインストールした方が良さそう。
Installing the AWS SAM CLI on macOS
$ brew update
$ brew upgrade
$ brew tap aws/tap
$ brew install aws-sam-cli
でインストールできる。正常にインストールできたら、
$ sam --version
SAM CLI, version 0.10.0
と表示される。
#プロジェクトの作成
SAMを使ってpython3.7でのプロジェクト(Lambda Function)の雛形を生成します。
$ sam init --runtime python3.7
以下のファイルが生成されます。
sam-app
├── README.md
├── hello_world
│ ├── __init__.py
│ ├── __pycache__
│ ├── app.py
│ └── requirements.txt
├── template.yaml
└── tests
└── unit
├── __init__.py
├── __pycache__
└── test_handler.py
#Unit Test
ユニットテストも生成されているので実行してみる。
$ cd sam-app
$ python -m purest tests/ -v
============================== test session starts ==============================
platform darwin -- Python 3.7.2, pytest-4.2.0, py-1.7.0, pluggy-0.8.1 -- /Users/tetsuo/.pyenv/versions/3.7.2/bin/python
cachedir: .pytest_cache
rootdir: /Users/tetsuo/devel/src/github/FirstFourNotes/contract-dev/ISO-L-Team/ISO-Seminar-backend/functions/sam-app, inifile:
plugins: mock-1.10.0
collected 1 item
tests/unit/test_handler.py::test_lambda_handler PASSED [100%]
============================== 1 passed in 0.10 seconds ==============================
生成したままなのでパスします。
Build
AWS Lambdaはリソース等をフラットにフォルダーに置かなければならないので、まず、ビルドします。
$ sam build
2019-02-03 16:30:59 Found credentials in shared credentials file: ~/.aws/credentials
2019-02-03 16:30:59 Building resource 'HelloWorldFunction'
2019-02-03 16:30:59 Running PythonPipBuilder:ResolveDependencies
2019-02-03 16:31:00 Running PythonPipBuilder:CopySource
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Package: sam package --s3-bucket <yourbucket>
#ローカルでの実行
$ sam local start-api
2019-02-03 18:00:04 Found credentials in shared credentials file: ~/.aws/credentials
2019-02-03 18:00:05 Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
2019-02-03 18:00:05 You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2019-02-03 18:00:05 * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
でサーバーが立ち上がる。ブラウザでhttp://127.0.0.1:3000/hello
にアクセスすると、
ブラウザの画面に
{"message": "hello world", "location": "39.111.112.54"}
と表示され、コマンドラインにも以下が表示される。
2019-02-03 18:00:18 Invoking app.lambda_handler (python3.7)
Fetching lambci/lambda:python3.7 Docker container image......
2019-02-03 18:00:20 Mounting /Users/tetsuo/devel/src/github/FirstFourNotes/contract-dev/ISO-L-Team/ISO-Seminar-backend/functions/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro inside runtime container
START RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72 Version: $LATEST
END RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72
REPORT RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72 Duration: 364.27 ms Billed Duration: 400 ms Memory Size: 128 MB Max Memory Used: 28 MB
2019-02-03 18:00:22 No Content-Type given. Defaulting to 'application/json'.
2019-02-03 18:00:22 127.0.0.1 - - [03/Feb/2019 18:00:22] "GET /hello HTTP/1.1" 200 -
#LocalStackとの連携
LocalStackを使うとS3やAPI Gatewayのアクセスをローカルで実行することができます。
S3を使う
AWSにデプロイする
##準備
インポートするモジュールは、requirements.txtに書いておきます。例えば、MuSQLとS3を使う場合、"pymysql"と"boto3"をインポートするので、requirements.txtは以下のようになります。
pymysql
boto3
##ビルド
アップロードに必要なモジュールやソースコードを集めてまとめます。
$ sam build
集められたファイルは.aws-sam/build
に置かれます。
##パッケージングとアップロード
ビルドしたファイルをパッケージにして、S3にアップロードします。アップロードする先のbucketは先に作っておきます。
ここではadmin-functionsというbucketにアップロードします。
# sam package --s3-bucket admin-functions
Uploading to 9e6330051e2955355ab532773cb70983 6405104 / 6405104.0 (100.00%)
AWSTemplateFormatVersion: '2010-09-09'
Description: 'import_attende
Sample SAM Template for import_attende
'
Globals:
Function:
Timeout: 30
Outputs: null
Resources:
ImportAttendeeFunction:
Properties:
CodeUri: s3://admin-functions/9e6330051e2955355ab532773cb70983
Environment:
Variables:
PARAM1: VALUE
Events:
UploadCSV:
Properties:
Bucket: admin-upload
Events: s3:ObjectCreated:*
Type: S3
Handler: app.lambda_handler
Runtime: python3.7
Type: AWS::Serverless::Function
SrcBucket:
Type: AWS::S3::Bucket
Transform: AWS::Serverless-2016-10-31
アップロードしたパッケージにアクセスするにはCodeUrl
を使います。上の場合は、s3://admin-functions/9e6330051e2955355ab532773cb70983
となります。
また、呼び出すハンドラー名はHandler
にあります。この場合は、app.lambda_handler
です。
これは、template.yml
で指定できます。
Lambda関数を実行する
AWS LambdaのFunctionsページで、上でアップロードした関数を使うFunctionを作成します。作成したら、そのFunctionのページを表示して、Function Code
の各項目を以下のように設定します。
項目 | 値 |
---|---|
Code entry type: | Upload a file from Amazon S3 |
Runtime | Python3.7 |
Handler | app.lambda_handler |
Amazon S3 link URL | s3://admin-functions/9e6330051e2955355ab532773cb70983" |
設定が終われば、右上のSave
ボタンを押します。これでLambda FunctionがS3から読み込まれ実行できるようになります。
Lambda関数をテストする
右上のTest
ボタンを押すと、初めてであればテスト用にイベントが作成され、表示されます。必要に応じてこれを編集しCreate
します。もう一度Test
ボタンを押すとLambda関数が呼び出され、先ほど作ったイベントが引数として渡されます。