Lambda ローカルでサンプルアプリを動かす

前回の記事でLambdaのローカル開発環境を構築したので、今回はAWSチュートリアルのサンプルをビルドして動かしてみる。

AWSチュートリアルは下記を参考にする。

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-getting-started-hello-world.html

前回執筆した記事は下記の通り。

https://qiita.com/nobumichi/items/e876a448b7be21e7e51a

作業環境

サンプルアプリ用の作業ディレクトリを作成する

任意の作業ディレクトリを作成する。私はDocuments配下にlambdaディレクトリを作成しました。 同様の場所に作業ディレクトリを作成する場合は、xxxxxxの部分は皆さんの環境に合わせて変更してください。

cd C:\Users\xxxxxx\Documents
mkidr lambda
cd .\lambda

サンプルアプリをダウンロードする

Windows Terminalを起動し、下記コマンドを実行する。

sam init

いきなり下記エラーメッセージが出た…

Error: Failed to modify a local file when cloning app templates. MAX_PATH should be enabled in the Windows registry.
For more details on how to enable MAX_PATH for Windows, please visit: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html

WindowsレジストリでMAX_PATHを有効にする必要があるそう。

エラーメッセージ中の下記サイトを訪れてみる。

https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html

下記Topicsの 3.Enable long paths (Windows 10 and newer only). の注意文を見てみると、Microsoftの開発ドキュメントを見てほしいとのこと。

To enable long paths, see Enable Long Paths in Windows 10, Version 1607, and Later in the Microsoft Windows App Development Documentation.

ということで、促されるままにMicrosoftの開発ドキュメントを見てみる。

すると、PowerShellを起動し、下記コマンドを実行せよとのこと。

New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force

管理者権限でWindows Terminalを起動しないと、下記のエラーメッセージが出てしまうので注意が必要。 参考サイトも一緒に貼り付けておく。

New-ItemProperty: Requested registry access is not allowed.

https://github.com/ChrisTitusTech/winutil/issues/386

Windows Terminalを起動し直した後に作業ディレクトリに移動し、下記コマンドを再度実行する。

sam init

無事に成功したようで、下記メッセージが出力された。 参考までに、以下にWindows Terminal上に表示されたやり取りをそのまま貼り付けておく。

You can preselect a particular runtime or package type when using the `sam init` experience.
Call `sam init --help` to learn more.

Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
        1 - Hello World Example
        2 - Multi-step workflow
        3 - Serverless API
        4 - Scheduled task
        5 - Standalone function
        6 - Data processing
        7 - Infrastructure event management
        8 - Serverless Connector Hello World Example
        9 - Multi-step workflow with Connectors
        10 - Lambda EFS example
        11 - Machine Learning
Template: 1

Use the most popular runtime and package type? (Python and zip) [y/N]: y

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: y
X-Ray will incur an additional cost. View https://aws.amazon.com/xray/pricing/ for more details

Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: y
AppInsights monitoring may incur additional cost. View https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/appinsights-what-is.html#appinsights-pricing for more details

Project name [sam-app]:   ← ここは空欄です。何も入力せずにエンターキー押下。

Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)

    -----------------------
    Generating application:
    -----------------------
    Name: sam-app
    Runtime: python3.9
    Architectures: x86_64
    Dependency Manager: pip
    Application Template: hello-world
    Output Directory: .

    Next steps can be found in the README file at ./sam-app/README.md


Commands you can use next
=========================
[*] Create pipeline: cd sam-app && sam pipeline init --bootstrap
[*] Validate SAM template: cd sam-app && sam validate
[*] Test Function in the Cloud: cd sam-app && sam sync --stack-name {stack-name} --watch

サンプルアプリをビルドする

サンプルアプリのtemplate.yamlファイルがあるプロジェクトディレクトリに移動する。 デフォルトではsam-appとなっている。

cd sam-app

下記コマンドを実行する。

sam build

見事にビルドが失敗した。ランタイムがPython3.9になっている模様。

Building codeuri: C:\Users\xxxxxx\Documents\lambda\sam-app\hello_world runtime: python3.9 metadata: {} architecture: x86_64 functions: HelloWorldFunction

Build Failed
Error: PythonPipBuilder:Validation - Binary validation failed for python, searched for python in following locations  : ['C:\\Users\\xxxxxx\\AppData\\Local\\Programs\\Python\\Python311\\python.EXE', 'C:\\Users\\xxxxxx\\AppData\\Local\\Microsoft\\WindowsApps\\python.EXE', 'C:\\Users\\xxxxxx\\AppData\\Local\\Microsoft\\WindowsApps\\python3.EXE'] which did not satisfy constraints for runtime: python3.9. Do you have python for runtime: python3.9 on your PATH?

そのため、RuntimeのPythonのバージョンを3.11に変更する。 template.yamlファイルはsam-appディレクトリ配下にある。

- Runtime: python3.9
+ Runtime: python3.11

再び、下記コマンドを実行する。

sam build
Building codeuri: C:\Users\xxxxxx\Documents\lambda\sam-app\hello_world runtime: python3.11 metadata: {} architecture: x86_64 functions: HelloWorldFunction

Build Failed
Error: 'python3.11' runtime is not supported

??

どうやら、ランタイムのPythonのバージョンは3.9までしかサポートしていないらしい…

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-runtimes.html

急遽、Macでお馴染みのpyenvをインストールし、3.9系最新のPython3.9.13をインストールした。

https://my-web-note.com/install_python_pyenv_windows/

Windows Terminalを起動し直し、Python3.9.13が使用可能なことを確認した。 そして、再び下記コマンドを実行する。

sam build
Building codeuri: C:\Users\のぶみち\Documents\lambda\sam-app\hello_world runtime: python3.9 metadata: {} architecture: x86_64 functions: HelloWorldFunction
Running PythonPipBuilder:ResolveDependencies

Build Failed
Error: PythonPipBuilder:ResolveDependencies - 'utf-8' codec can't decode byte 0x82 in position 765: invalid start byte

??

色々調べたが、このエラーの原因はよく分からなかった…

sam-appディレクトリ配下のREADME.mdを見ると、ローカルのテストでは下記コマンドを使用せよとのこと。 試しに実行したらビルドが成功した。

Use the SAM CLI to build and test locally Build your application with the sam build --use-container command. sam-app$ sam build --use-container

sam build --use-container

以下にビルド時のログを貼り付けておく。 Docker container imageのロードに結構時間がかかった。

Starting Build inside a container
Building codeuri: C:\Users\xxxxxx\Documents\lambda\sam-app\hello_world runtime: python3.9 metadata: {} architecture: x86_64 functions: HelloWorldFunction

Fetching public.ecr.aws/sam/build-python3.9:latest-x86_64 Docker container image...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Mounting C:\Users\xxxxxx\Documents\lambda\sam-app\hello_world as /tmp/samcli/source:ro,delegated inside runtime container

Build Succeeded

Built Artifacts  : .aws-sam\build
Built Template   : .aws-sam\build\template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource

サンプルアプリをローカルでテストする

下記コマンドを実行する。

sam local start-api

下記のようなメッセージが出力されれば、動作確認の準備が完了となる。

Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
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. If you used sam build before running local commands, you will need to re-run sam build for the changes to be picked up. You only need to restart SAM CLI if you update your AWS SAM template
2023-01-03 18:06:07  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
Invoking app.lambda_handler (python3.9)
Image was not found.
Removing rapid images for repo public.ecr.aws/sam/emulation-python3.9
Building image...Invoking app.lambda_handler (python3.9)
Image was not found.
Removing rapid images for repo public.ecr.aws/sam/emulation-python3.9
Building image...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
....Skip pulling image and use local one: public.ecr.aws/sam/emulation-python3.9:rapid-1.67.0-x86_64.

Mounting C:\Users\xxxxxx\Documents\lambda\sam-app\.aws-sam\build\HelloWorldFunction as /var/task:ro,delegated inside runtime container
.
Skip pulling image and use local one: public.ecr.aws/sam/emulation-python3.9:rapid-1.67.0-x86_64.

Mounting C:\Users\xxxxxx\Documents\lambda\sam-app\.aws-sam\build\HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: a413c2a5-b64a-4973-a621-38acc4762742 Version: $LATEST
START RequestId: 84c14d09-78bf-4cc1-9316-960d5ab62847 Version: $LATEST
END RequestId: a413c2a5-b64a-4973-a621-38acc4762742
REPORT RequestId: a413c2a5-b64a-4973-a621-38acc4762742  Init Duration: 0.55 ms  Duration: 1232.29 ms    Billed Duration: 1233 ms        Memory Size: 128 MB     Max Memory Used: 128 MB
END RequestId: 84c14d09-78bf-4cc1-9316-960d5ab62847
REPORT RequestId: 84c14d09-78bf-4cc1-9316-960d5ab62847  Init Duration: 0.41 ms  Duration: 980.83 ms     Billed Duration: 981 ms Memory Size: 128 MB     Max Memory Used: 128 MB
No Content-Type given. Defaulting to 'application/json'.
2023-01-03 18:12:47 127.0.0.1 - - [03/Jan/2023 18:12:47] "GET /hello HTTP/1.1" 200 -

試しにcurlコマンドでリクエストを送信してみる。

curl http://127.0.0.1:3000/hello

下記が表示されることを確認する。

{"message": "hello world"}

下記コマンドでLambda関数を直接呼び出すこともできるらしい。

sam local invoke "HelloWorldFunction" -e events/event.json

下記のようなログが表示されることを確認する。

Invoking app.lambda_handler (python3.9)
Skip pulling image and use local one: public.ecr.aws/sam/emulation-python3.9:rapid-1.67.0-x86_64.

Mounting C:\Users\xxxxxx\Documents\lambda\sam-app\.aws-sam\build\HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: 36a75d90-f84f-4fc1-9f08-0dbd1be90e3b Version: $LATEST
END RequestId: 36a75d90-f84f-4fc1-9f08-0dbd1be90e3b
REPORT RequestId: 36a75d90-f84f-4fc1-9f08-0dbd1be90e3b  Init Duration: 0.18 ms  Duration: 192.46 ms     Billed Duration: 193 ms Memory Size: 128 MB     Max Memory Used: 128 MB
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}

参考文献

以上。