プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

pyenv を 2.3.18 から 2.4.22 へアップデート

pyenv でインストールできる python のバージョンを表示してみると

mor@DESKTOP-DE7IL4F:~$ pyenv install --list
Available versions:
  2.1.3
  2.2.3
  2.3.7
  2.4.0
(略)
  3.11.4
  3.12.0b2
  3.12-dev
  3.13-dev
  activepython-2.7.14
(略)

となり、 python 3.13 が一覧に出てこない。

同じことに困っている人はいるようで、

pyenvのlistが更新されない時 #pyenv - Qiita

こちらの記事をみると、 pyenv のアップデートをする必要があるっぽい。なので、やってみます。

アップデート

今の pyenv は こちらの記事にあるように git clone でインストールしたもので、バージョンは

mor@DESKTOP-DE7IL4F:~$ pyenv -v
pyenv 2.3.18-9-ge0084304

です。どうも、作業時の最新版を入れたのであって、リリースのタグを入れたんじゃなかったんですね。

なので、こちらの公式の upgrading の手順に従って、

mor@DESKTOP-DE7IL4F:~$ cd .pyenv/
mor@DESKTOP-DE7IL4F:~/.pyenv$ git fetch
remote: Enumerating objects: 1587, done.
remote: Counting objects: 100% (871/871), done.
remote: Compressing objects: 100% (170/170), done.
remote: Total 1587 (delta 749), reused 774 (delta 690), pack-reused 716 (from 1)
Receiving objects: 100% (1587/1587), 961.16 KiB | 2.13 MiB/s, done.
Resolving deltas: 100% (990/990), completed with 80 local objects.
From https://github.com/pyenv/pyenv
   e0084304..d04a081d  master     -> origin/master
 * [new tag]           v2.4.22    -> v2.4.22
 * [new tag]           2.3.30     -> 2.3.30

tag を確認します。

mor@DESKTOP-DE7IL4F:~/.pyenv$ git tag
1.2.24
1.2.24.1
(略)
v2.4.21
v2.4.22
v2.4.3
(略)

一番最新が v2.4.22 なので、それに切り替えます。

mor@DESKTOP-DE7IL4F:~/.pyenv$ git checkout v2.4.22
Note: switching to 'v2.4.22'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at d04a081d 2.4.22
mor@DESKTOP-DE7IL4F:~/.pyenv$

問題なさそうですね。

確認

pyenv のバージョン

mor@DESKTOP-DE7IL4F:~$ pyenv --version
pyenv 2.4.22
mor@DESKTOP-DE7IL4F:~$

新しくなってますね。インストールできる python のバージョンも確認します。

mor@DESKTOP-DE7IL4F:~$ pyenv install --list
Available versions:
  2.1.3
(略)
  3.11.4
  3.11.5
  3.11.6
  3.11.7
  3.11.8
  3.11.9
  3.11.10
  3.11.11
  3.12.0
  3.12-dev
  3.12.1
  3.12.2
  3.12.3
  3.12.4
  3.12.5
  3.12.6
  3.12.7
  3.12.8
  3.13.0
  3.13.0t
  3.13-dev
  3.13t-dev
  3.13.1
  3.13.1t
  3.14.0a2
  3.14.0a2t
  3.14-dev
  3.14t-dev
  activepython-2.7.14
(略)

増えてますね。これで、新しめの python をインストールできます。

mor@DESKTOP-DE7IL4F:~$ pyenv install 3.13.1
Downloading Python-3.13.1.tar.xz...
-> https://www.python.org/ftp/python/3.13.1/Python-3.13.1.tar.xz
Installing Python-3.13.1...
Installed Python-3.13.1 to /home/mor/.pyenv/versions/3.13.1
mor@DESKTOP-DE7IL4F:~$

できました。今インストールしているバージョンを確認すると

mor@DESKTOP-DE7IL4F:~$ pyenv versions
* system (set by /home/mor/.pyenv/version)
  3.11.4
  3.13.1
mor@DESKTOP-DE7IL4F:~$

入ってますね。

余談

pyenv のインストールを git clone でやったんですが、 pyenv-installer というのを使えば、簡単にインストールができたようです。

pyenvを一発でインストールする方法 - kumilog.net

別段、このままでも困らないといえば困らないのですが、 pyenv-installer のほうがアップデートも簡単にできるので、こちらに切り替えられなかな?と考えています。

そのうち試そうかな。

WSL 上に Lambda のローカル実行環境を作る:aws にデプロイ (3/3)

次は aws 側(クラウド側)にデプロイしてみます。

デプロイ

当初から参考にしていたこちらのシリーズの記事

サーバーレスのローカル開発環境を整備する ~後編 - 変化を求めるデベロッパーを応援するウェブマガジン | AWS

では、デプロイにも触れてますが、かなりざっくりとしています。

実際の選択肢などは、こちらのチュートリアルのほうが詳しいです。

チュートリアル: で Hello World アプリケーションをデプロイする AWS SAM - AWS Serverless Application Model

ということで、この部分はこのチュートリアルに従ってやってみたいと思います。

早速やってみます。

複数のプロファイルがあるので、デプロイコマンドを呼び出す際に、プロファイル名を引数で与えます。

(.venv) mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$ sam deploy --guided --profile sample_prof

Configuring SAM deploy
======================

        Looking for config file [samconfig.toml] :  Found
        Reading default arguments  :  Success

        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [sam-hello-world]:
        AWS Region [us-east-1]: ap-northeast-1
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [Y/n]: n
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]:
        #Preserves the state of previously provisioned resources when an operation fails
        Disable rollback [y/N]:
        HelloWorldFunction has no authentication. Is this okay? [y/N]: y
        Save arguments to configuration file [Y/n]:
        SAM configuration file [samconfig.toml]:
        SAM configuration environment [default]:

各オプションは、チュートリアルに従いました。ここまで入力すると、デプロイが始まります。

ですが、なんと、エラーになりました。

Error: Failed to create/update the stack: sam-hello-world, Waiter StackCreateComplete failed: Waiter encountered a terminal failure state: For expression "Stacks[].StackStatus" we matched expected path: "ROLLBACK_FAILED" at least once

詳細が出ているので、追いかけると

Resource handler returned message:
"Encountered a permissions error performing a
tagging operation, please add required tag
permissions. See
https://repost.aws/knowledge-
center/cloudformation-tagging-permission-
error for how to resolve. Resource handler
returned message: "User:
arn:aws:iam::xxxxxxxxxxxx:user/sample_prof
is not authorized to perform: iam:CreateRole
on resource:
arn:aws:iam::xxxxxxxxxxxx:role/sam-hello-
world-HelloWorldFunctionRole-xxxxxxxxxxxx
because no identity-based policy allows the
iam:CreateRole action (Service: Iam, Status
Code: 403, Request ID:
xxxxxxxxxxxxxxxx)""
RequestToken:
xxxxxxxxxxxxxxxx,
HandlerErrorCode:
UnauthorizedTaggingOperation)

iam の CreateRole の権限がないためのエラーのようです。

IAM ユーザーの権限を追加

権限でエラーが起きているとなると、表示された権限以外にも必要な権限がありそうです。ということで、ネットを調べてみると、下記の記事に必要な権限一覧がありました。

AWS Lambdaのデプロイに必要なIAMポリシーについて #lambda - Qiita

今、試しているアカウントは、テスト用ということで、 PowerUserAccess の権限を与えています。この権限だと、IAM 関連の権限に制限が入っているので、これだけ、追加で許可してやることにします。

ということで、下記のようなポリシーを作成して、このアカウントにアタッチしておきます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "iam:GetRole",
                "iam:PassRole",
                "iam:DetachRolePolicy",
                "iam:TagRole",
                "iam:CreateRole",
                "iam:DeleteRole",
                "iam:AttachRolePolicy",
                "iam:UpdateRole",
                "iam:PutRolePolicy",
                "iam:CreateUser"
            ],
            "Resource": "*"
        }
    ]
}

上記の記事の権限に加えて、 iam:TagRole を追加しています(何度か試した結果、これも必要だと怒られたためです)。

デプロイ失敗時のリソースを削除

再度デプロイを試す前に、作成途中のリソースを一度、削除しておきます。

(.venv) mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$ sam delete --profile sample_prof
        Are you sure you want to delete the stack sam-hello-world in the region ap-northeast-1 ? [y/N]: y
        Are you sure you want to delete the folder sam-hello-world in S3 which contains the artifacts? [y/N]: y
        - Deleting S3 object with key sam-hello-world/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        - Deleting S3 object with key sam-hello-world/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.template
        - Deleting Cloudformation stack sam-hello-world

Deleted successfully
(.venv) mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$

で、これで全部消えたかと思って、念のために aws のコンソールから見てみると、 CloudFormation にスタックが残ってます。

どうも、これは SAM で共通に使う S3 バケットのようです。

もう一度、最初から作るのを確認したいので、これも削除しておきます。

なお、 CloudFormation でスタックの削除を行っても、エラーで消えない場合があります。これは、 S3 のバケット内にオブジェクトが残っていると消えないためです。しかし、バケットを見てもオブジェクトがありません。

が、これはバージョニングが有効になっている場合に、古いオブジェクトがあるとエラーになるという罠になってます。実際、『バージョンの表示』をクリックすると消えたはずのオブジェクトが再度表示されます。

ということで、

AWS S3 クイズ ~バケットが空ではない?~ #AWS - Qiita

の記事などを参考にして、バケットからオブジェクトをすべて削除しておいてから、 CloudFormation のスタックを削除します。または、一度 CloudFormation で削除に失敗すると、同じスタックの再削除の際に以前失敗したリソースの削除をスキップするか尋ねられるので、そちらではスキップを選択してスタックを削除後、手作業で S3 バケットを消すという方法もあります。

いずれにしても無事に消えたのを確認しておきます。

再デプロイ

一度、きれいにしたら、再度デプロイです。

(.venv) mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$ sam deploy --guided --profile sample_prof

Configuring SAM deploy
======================

        Looking for config file [samconfig.toml] :  Found
        Reading default arguments  :  Success

        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [sam-hello-world]:
        AWS Region [ap-northeast-1]:
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [Y/n]: n
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]:
        #Preserves the state of previously provisioned resources when an operation fails
        Disable rollback [y/N]:
        HelloWorldFunction has no authentication. Is this okay? [y/N]: y
        Save arguments to configuration file [Y/n]:
        SAM configuration file [samconfig.toml]:
        SAM configuration environment [default]:

        Looking for resources needed for deployment:
        Creating the required resources...
        Successfully created!

        Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-xxxxxxxxxx
        A different default S3 bucket can be set in samconfig.toml and auto resolution of buckets turned off by setting resolve_s3=False

        Parameter "stack_name=sam-hello-world" in [default.deploy.parameters] is defined as a global parameter [default.global.parameters].
        This parameter will be only saved under [default.global.parameters] in /home/mor/tmp/sam_samples/sam-hello-world/samconfig.toml.

        Saved arguments to config file
        Running 'sam deploy' for future deployments will use the parameters saved above.
        The above parameters can be changed by modifying samconfig.toml
        Learn more about samconfig.toml syntax at
        https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html

        Uploading to sam-hello-world/ea54f8c447ec2d2acbd568a24d797ab4  573488 / 573488  (100.00%)

        Deploying with following values
        ===============================
        Stack name                   : sam-hello-world
        Region                       : ap-northeast-1
        Confirm changeset            : False
        Disable rollback             : False
        Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-xxxxxxxxxx
        Capabilities                 : ["CAPABILITY_IAM"]
        Parameter overrides          : {}
        Signing Profiles             : {}

Initiating deployment
=====================

        Uploading to sam-hello-world/89c7047fabf664fbcdcbd705c01e8d9d.template  1204 / 1204  (100.00%)


Waiting for changeset to be created..

CloudFormation stack changeset
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Operation                                       LogicalResourceId                               ResourceType                                    Replacement
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ Add                                           HelloWorldFunctionHelloWorldPermissionProd      AWS::Lambda::Permission                         N/A
+ Add                                           HelloWorldFunctionRole                          AWS::IAM::Role                                  N/A
+ Add                                           HelloWorldFunction                              AWS::Lambda::Function                           N/A
+ Add                                           ServerlessRestApiDeploymentxxxxxxxxxx           AWS::ApiGateway::Deployment                     N/A
+ Add                                           ServerlessRestApiProdStage                      AWS::ApiGateway::Stage                          N/A
+ Add                                           ServerlessRestApi                               AWS::ApiGateway::RestApi                        N/A
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxx:changeSet/samcli-deploy1733987739/541c8bc1-81e7-436f-b68c-7326d868a648


2024-12-12 16:15:45 - Waiting for stack create/update to complete

CloudFormation events from stack operations (refresh every 5.0 seconds)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus                                  ResourceType                                    LogicalResourceId                               ResourceStatusReason
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS                              AWS::CloudFormation::Stack                      sam-hello-world                                 User Initiated
CREATE_IN_PROGRESS                              AWS::IAM::Role                                  HelloWorldFunctionRole                          -
CREATE_IN_PROGRESS                              AWS::IAM::Role                                  HelloWorldFunctionRole                          Resource creation Initiated
CREATE_COMPLETE                                 AWS::IAM::Role                                  HelloWorldFunctionRole                          -
CREATE_IN_PROGRESS                              AWS::Lambda::Function                           HelloWorldFunction                              -
CREATE_IN_PROGRESS                              AWS::Lambda::Function                           HelloWorldFunction                              Resource creation Initiated
CREATE_IN_PROGRESS - CONFIGURATION_COMPLETE     AWS::Lambda::Function                           HelloWorldFunction                              Eventual consistency check initiated
CREATE_IN_PROGRESS                              AWS::ApiGateway::RestApi                        ServerlessRestApi                               -
CREATE_IN_PROGRESS                              AWS::ApiGateway::RestApi                        ServerlessRestApi                               Resource creation Initiated
CREATE_COMPLETE                                 AWS::ApiGateway::RestApi                        ServerlessRestApi                               -
CREATE_IN_PROGRESS                              AWS::ApiGateway::Deployment                     ServerlessRestApiDeploymentxxxxxxxxxx           -
CREATE_IN_PROGRESS                              AWS::Lambda::Permission                         HelloWorldFunctionHelloWorldPermissionProd      -
CREATE_IN_PROGRESS                              AWS::Lambda::Permission                         HelloWorldFunctionHelloWorldPermissionProd      Resource creation Initiated
CREATE_COMPLETE                                 AWS::Lambda::Function                           HelloWorldFunction                              -
CREATE_COMPLETE                                 AWS::Lambda::Permission                         HelloWorldFunctionHelloWorldPermissionProd      -
CREATE_IN_PROGRESS                              AWS::ApiGateway::Deployment                     ServerlessRestApiDeploymentxxxxxxxxxx           Resource creation Initiated
CREATE_COMPLETE                                 AWS::ApiGateway::Deployment                     ServerlessRestApiDeploymentxxxxxxxxxx           -
CREATE_IN_PROGRESS                              AWS::ApiGateway::Stage                          ServerlessRestApiProdStage                      -
CREATE_IN_PROGRESS                              AWS::ApiGateway::Stage                          ServerlessRestApiProdStage                      Resource creation Initiated
CREATE_COMPLETE                                 AWS::ApiGateway::Stage                          ServerlessRestApiProdStage                      -
CREATE_COMPLETE                                 AWS::CloudFormation::Stack                      sam-hello-world                                 -
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

CloudFormation outputs from deployed stack
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole
Description         Implicit IAM Role created for Hello World function
Value               arn:aws:iam::xxxxxxxxxx:role/sam-hello-world-HelloWorldFunctionRole-xxxxxxxxxx

Key                 HelloWorldApi
Description         API Gateway endpoint URL for Prod stage for Hello World function
Value               https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/

Key                 HelloWorldFunction
Description         Hello World Lambda Function ARN
Value               arn:aws:lambda:ap-northeast-1:xxxxxxxxxx:function:sam-hello-world-HelloWorldFunction-xxxxxxxxxx
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Successfully created/updated stack - sam-hello-world in ap-northeast-1

(.venv) mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$

やっとうまくいきましたね。

作成されたリソースの確認

一応、作成されたものを確認しておきます。CLoudFormation をみると、スタックが2つ作られています。

sam-hello-world という名前のスタックが今回のアプリケーション固有のスタックです。

一方、 aws-sam-cli-managed-default のスタックは SAM で共通に使うスタックのようです。中身は S3 のバケット(とバケットポリシー)になります。

SAMでは S3 に一旦アップロードしてから、Lambdaに展開するそうです。こちらの公式ドキュメントにある、デプロイ内容の説明で、

必要に応じて、 AWS SAM CLI は新しいバケットを作成します

にある説明に対応する部分ですね。

sam-hello-world というコマンドラインで指定したスタック名は、

こんな感じになってます。今回の場合は、

  • Lambda
  • API Gateway
  • IAM Role

が含まれており、それに関するリソースも作られているという感じです。SAM により作られるリソースについては、

serverless-application-model/docs/internals/generated_resources.rst at master · aws/serverless-application-model · GitHub

こちらなどに詳しいです。

にしても、これは楽ですね。

動作確認

歳ほどのデプロイ時に表示されたURLに、ブラウザでアクセスしてみると

のように、 hello world が表示されました。ちゃんと動作しているっぽいですね。

後始末

最後は、後始末しておきます。

(.venv) mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$ sam delete --profile sample_prof
        Are you sure you want to delete the stack sam-hello-world in the region ap-northeast-1 ? [y/N]: y
        Are you sure you want to delete the folder sam-hello-world in S3 which contains the artifacts? [y/N]: y
        - Deleting S3 object with key sam-hello-world/ea54f8c447ec2d2acbd568a24d797ab4
        - Deleting S3 object with key sam-hello-world/89c7047fabf664fbcdcbd705c01e8d9d.template
        - Deleting Cloudformation stack sam-hello-world

Deleted successfully
(.venv) mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$

ただし、S3 のバケット自体(および S3 のバケットを作った際の CloudFormation)は削除されません。

まとめ

SAM なかなか便利そうでうね。ただ、構成変えると権限周りが変わるので、そのあたりがちょっとめんどそうです。

ま、いろいろと試したいと思います。

WSL 上に Lambda のローカル実行環境を作る:ローカルでデバッグ (2/3)

下記のシリーズの続きです。

実行環境ができたので、早速サンプルを試してみます。

サーバーレスのローカル開発環境を整備する ~中編 - 変化を求めるデベロッパーを応援するウェブマガジン | AWS

TODO たぶんなくす チュートリアル: で Hello World アプリケーションをデプロイする AWS SAM - AWS Serverless Application Model

プロジェクトを作成

まずは、参考記事にあるサンプルを作ってみます。記事は Java の例ですが、ここでは Python を選んでみます。

SAM CLI を使って、プロジェクトの作成を呼び出します。

mor@DESKTOP-DE7IL4F:~/tmp/sam_samples$ sam init

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 - Data processing
        3 - Hello World Example with Powertools for AWS Lambda
        4 - Multi-step workflow
        5 - Scheduled task
        6 - Standalone function
        7 - Serverless API
        8 - Infrastructure event management
        9 - Lambda Response Streaming
        10 - Serverless Connector Hello World Example
        11 - Multi-step workflow with Connectors
        12 - GraphQLApi Hello World Example
        13 - Full Stack
        14 - Lambda EFS example
        15 - DynamoDB Example
        16 - Machine Learning
Template: 1

まずは、 Hello World のサンプルを選びます。この Hello World のサンプルは API Gateway + Lambda で構成されていて、 http リクエストを受けて、応答を返すというサンプルになります。

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

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]:

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]:

Would you like to set Structured Logging in JSON format on your Lambda functions?  [y/N]:

Project name [sam-app]: sam-hello-world

ランタイムとして、 Python が推奨されているので、そのまま選びます。あとはプロジェクト名以外はデフォルト値とします。

    -----------------------
    Generating application:
    -----------------------
    Name: sam-hello-world
    Runtime: python3.13
    Architectures: x86_64
    Dependency Manager: pip
    Application Template: hello-world
    Output Directory: .
    Configuration file: sam-hello-world/samconfig.toml

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


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

mor@DESKTOP-DE7IL4F:~/tmp/sam_samples$

作成が完了すると、こんな感じの表示になります。テンプレートから作られたファイルを確認するとこんな感じでした。

mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$ tree
.
├── README.md
├── __init__.py
├── events
│   └── event.json
├── hello_world
│   ├── __init__.py
│   ├── app.py
│   └── requirements.txt
├── samconfig.toml
├── template.yaml
└── tests
    ├── __init__.py
    ├── integration
    │   ├── __init__.py
    │   └── test_api_gateway.py
    ├── requirements.txt
    └── unit
        ├── __init__.py
        └── test_handler.py

6 directories, 14 files
mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$

ちなみに、初めて、 sam init でアプリケーションを作ったときは、 *.py とかテスト用の test フォルダが作られていませんでした。何度か試すうちにいつのまにやら作られるようになってました。謎だ。

ビルド

ここで、サンプルアプリケーションができたので、一度ビルドできるか試してみます。

mor@DESKTOP-DE7IL4F:~/tmp/sam_samples$ cd sam-hello-world/
mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$ sam build
Starting Build use cache
Manifest file is changed (new hash: 3298f13049d19cffaa37ca931dd4d421) or dependency folder (.aws-sam/deps/137a595b-8df5-4f3b-bc3f-6a253fdf30f5) is missing for (HelloWorldFunction), downloading
dependencies and copying/building source
Building codeuri: /home/mor/tmp/sam_samples/sam-hello-world/hello_world runtime: python3.13 architecture: x86_64 functions: HelloWorldFunction

Build Failed
Error: PythonPipBuilder:Validation - Binary validation failed for python, searched for python in following locations  : ['/home/mor/.pyenv/shims/python', '/home/mor/.pyenv/shims/python3', '/usr/bin/python3', '/bin/python3'] which did not satisfy constraints for runtime: python3.13. Do you have python for runtime: python3.13 on your PATH?
mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$

おっと、 python 3.13 が入ってないと怒られました。

このサンプルディレクトリの python を 3.13 に切り替えます。

mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$ pyenv local 3.13.1
mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$ python3 --version
Python 3.13.1
mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$

やり直します。

mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$ sam build
Starting Build use cache
Manifest file is changed (new hash: 3298f13049d19cffaa37ca931dd4d421) or dependency folder (.aws-sam/deps/137a595b-8df5-4f3b-bc3f-6a253fdf30f5) is missing for (HelloWorldFunction), downloading
dependencies and copying/building source
Building codeuri: /home/mor/tmp/sam_samples/sam-hello-world/hello_world runtime: python3.13 architecture: x86_64 functions: HelloWorldFunction
 Running PythonPipBuilder:CleanUp
 Running PythonPipBuilder:ResolveDependencies
 Running PythonPipBuilder:CopySource
 Running PythonPipBuilder:CopySource

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
mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$

無事にビルドできましたね。

なお、上記とは本質的に関係ありませんが、ついでに venv も設定しておきます。

mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$ python3 -m venv .venv
mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$ . .venv/bin/activate
(.venv) mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$

VSCode で開く

では、次は VSCode で開いて、デバッグを試します。

VSCode を立ち上げます。WSLに接続していない時は、接続します。次に、作成したアプリケーションフォルダを選択します。

問題なく開けますね。

デバッグ構成を設定

記事に従って、デバッグ構成を設定します。当初は、

のように、デバッグ構成に関するヒントが出ていないので、設定を変更します。

VSCode の設定を開いて、『拡張機能』、『AWS Toolkit』を選択して、『Enable Code Lens』にチェックを入れて有効にします。

設定後、再度 app.py を表示すると

のように、デバッグ設定追加用のヒントが出るので、クリックします。クリックすると、

のように、どの構成を追加すると聞かれるので、最初は HelloWorldFunction を選択します。これは、 Lambda 関数を単体として動かす際の設定に該当します。

作成された launch.json は

{
    "configurations": [
        {
            "type": "aws-sam",
            "request": "direct-invoke",
            "name": "sam-hello-world:HelloWorldFunction",
            "invokeTarget": {
                "target": "template",
                "templatePath": "${workspaceFolder}/template.yaml",
                "logicalId": "HelloWorldFunction"
            },
            "lambda": {
                "payload": {},
                "environmentVariables": {}
            }
        }
    ]
}

こんな感じです。 Lambda は API Gateway 経由で呼ばれることが想定されているので、引数が必要になります。これを指定するために payload を

            "lambda": {
                "payload": {
                    "path": "${workspaceFolder}/events/event.json"
                },
                "environmentVariables": {}
            }

と修正します。テンプレートから作成した際の events/event.json はここで使うんですね。

次に、もう一度ヒントから『Add Debug Configuration』を選択して、『HelloWorldFunction(API Event) 』も追加しておきます。最終的に作成された launch.json はこんな感じになります。

{
    "configurations": [
        {
            "type": "aws-sam",
            "request": "direct-invoke",
            "name": "API sam-hello-world:HelloWorldFunction",
            "invokeTarget": {
                "target": "api",
                "templatePath": "${workspaceFolder}/template.yaml",
                "logicalId": "HelloWorldFunction"
            },
            "api": {
                "path": "/hello",
                "httpMethod": "get",
                "payload": {
                    "json": {}
                }
            }
        },
        {
            "type": "aws-sam",
            "request": "direct-invoke",
            "name": "sam-hello-world:HelloWorldFunction",
            "invokeTarget": {
                "target": "template",
                "templatePath": "${workspaceFolder}/template.yaml",
                "logicalId": "HelloWorldFunction"
            },
            "lambda": {
                "payload": {
                    "path": "${workspaceFolder}/events/event.json"
                },
                "environmentVariables": {}
            }
        }
    ]
}

VSCode で実行

サイドパネルの『実行とデバッグ』アイコンをクリックして、デバッグ構成として『 sam-hello-world:HelloWorldFunction 』を選択します。

次に、画面上部の実行ボタンを押します。すると、ビルドが走り、ブレークポイントで止まります。

簡単ですね。デバッグ構成の payload で指定した events/event.json ファイルの中身が、lambda_hander にわたってきてるのがわかります。

一方、デバッグ構成で『API sam-hello-world:HelloWorldFunction』を選択すると、バックグラウンドでサーバーが起動して、サーバー経由でリクエストがある場合のデバッグになるようです。

素朴な疑問やけど、 VSCode で使う時、『API ~』のデバッグ構成って使うのかな?

この記事にも書いてあるけど、 SAM CLI のコマンドラインから、ローカルサーバーを立ち上げておいて、何度も修正するような場合は使うような気もするけどどうなんだろうか?このあたりは、ま、徐々に試していきましょう。

まとめ

これで、 Lmbda をローカルで実行やデバッグができるようになりました。次はこれを aws 上にデプロイしてみようと思います。