AWS Toolkit または SAM CLI を使って、Lambda 関数をデプロイできるようになりました。
次は、 API Gateway + Lambda の Hello World のサンプルから一歩進めて、 Lambda 関数のみの構成をデプロイしてみます(進んでんのか?)。
- WSL, Ubuntu 24.04.1
- SAM CLI 1.131
- AWS CLI 2.2.42
SAM CLI でのアプリケーション作成
VSCode の SAM アプリケーションの新規作成では、 Lambda 関数のみのテンプレートがないので、コマンドラインから実行します。
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: 6
SAM CLI であれば、『Standalone function』が選択できます。しかし、
Which runtime would you like to use? 1 - dotnet8 2 - dotnet6 3 - nodejs22.x 4 - nodejs20.x 5 - nodejs18.x 6 - nodejs16.x Runtime: ^CAborted! mor@DESKTOP-DE7IL4F:~/tmp/sam_samples$
なんとこの場合、ランタイムは dotnet と Node.js のみです。Python がない。なんとまあ。
Hello World サンプルからの作成
そこで、世の中の人はどうしているのか調べてみると、
- AWS SAM Lambda関数だけを単体でデプロイしたいときのテンプレート設定例 | DevelopersIO
- 【Python】AWS SAMでLambda単体デプロイ【AWS】 - nomurabbitのブログ
などの記事が見つかります。
要は、 Hello World のテンプレートで新規アプリケーションを作成して、 API Gateway に関する記述を削除する、というやり方ですね。
ということで、やってみます。
まずは、 Hello World アプリケーションを作成します。VSCode でもコマンドラインでもお好きなほうで OK です。ランタイムは Python を選んでおきます。アプリケーションができたら、 template.yaml を編集します。
変更前
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > sam-lambda-only Sample SAM Template for sam-lambda-only # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 3 Resources: HelloWorldFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: hello_world/ Handler: app.lambda_handler Runtime: python3.13 Architectures: - x86_64 Events: HelloWorld: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /hello Method: get Outputs: # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function # Find out more about other implicit resources you can reference within SAM # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api HelloWorldApi: Description: "API Gateway endpoint URL for Prod stage for Hello World function" Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/" HelloWorldFunction: Description: "Hello World Lambda Function ARN" Value: !GetAtt HelloWorldFunction.Arn HelloWorldFunctionIamRole: Description: "Implicit IAM Role created for Hello World function" Value: !GetAtt HelloWorldFunctionRole.Arn
変更後
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > sam-lambda-only Sample SAM Template for sam-lambda-only # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 3 Resources: LambdaOnlyFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: FunctionName: "lamuda-only" Description: "sample lambda function only application created by SAM" CodeUri: lambda-src/ Handler: app.lambda_handler Runtime: python3.13 Architectures: - x86_64 # Events: # HelloWorld: # Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api # Properties: # Path: /hello # Method: get #Outputs: # # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function # # Find out more about other implicit resources you can reference within SAM # # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api # HelloWorldApi: # Description: "API Gateway endpoint URL for Prod stage for Hello World function" # Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/" # HelloWorldFunction: # Description: "Hello World Lambda Function ARN" # Value: !GetAtt HelloWorldFunction.Arn # HelloWorldFunctionIamRole: # Description: "Implicit IAM Role created for Hello World function" # Value: !GetAtt HelloWorldFunctionRole.Arn
のようにしました。主な変更点としては、
- Resources の 論理名を HelloWorldFunction から LambdaOnlyFunction に変更
- Resources の LambdaOnlyFunction 定義の Properties に FunctionName と Description を追加
- Resources の LambdaOnlyFunction 定義の Properties の CodeUri を適切な名前に変更
- Resources の LambdaOnlyFunction 定義の Events 以下を削除
- Outputs を無くす
としました。
1つ目の Resources の HelloWorldFunction の部分は、論理名として扱われるとのことなので、わかりやすい名前に変えてみました。
また、3つ目の CodeUri ですが、SAMで扱う分には、関数本体のファイルがあるフォルダを指せばよさそうです。
この変更に伴い、ローカルのフォルダ名も lambda-src に変更しました。
4つ目の Events の記述があることで API Gateway のリソースが作成されるので、ここを削除しています。
あと、デプロイは VSCode でやるつもりなんですが、この場合デフォルトだと S3 バケットにフォルダが作られないので、 samconfig.toml に s3_prefix を追加しておきます。
アプリケーション作成直後
[default.deploy.parameters] capabilities = "CAPABILITY_IAM" confirm_changeset = true resolve_s3 = true
s3_prefix を追加
[default.deploy.parameters] capabilities = "CAPABILITY_IAM" confirm_changeset = true resolve_s3 = true s3_prefix = "lambda_only_sample"
デプロイ
これで一度デプロイしてみます。デプロイは、 VSCode からやってみました。
こんな感じで問題なくデプロイできますね。なお、 Outputs がないため、画面に ARN 等が表示されていないことがわかります。こちらの記事だと、 Outputs を無くせなかったとあったのですが、 SAM CLI のバージョンアップに伴い仕様が変わったんですかね?今はなくしても問題ないようです。
aws 側も確認してみます。
CloudFormation の sam-lambda-only スタックを表示すると
こんな感じになり、 Lambda と IAM Role のみが作成された形になっています。また、この論理ID(論理名)が、先ほど template.yaml で変更した LambdaOnlyFunction に対応するものになっていることもわかります。
Lambda を見てみると、
関数名が FunctionName で指定した lamuda-only になっていることがわかります(間違えたつづりにしています)。API Gateway がないこともわかります。また、追加した Description も反映されています。
ただ、残念ながら、 samconfig.toml に設定した s3_prefix は消えてました。デプロイ時に samconfig.toml を書き換えるためなんでしょうね、きっと。このため、 S3 バケットの直下にファイルがアップロードされたようです。
なお、一度デプロイに成功したら、 s3_prefix を追加してデプロイしても『Use default values from samconfig』を選べば反映されました。
テスト
大丈夫だと思いますが、テストしておきます。
VSCode のサイドパネルから aws を選び、 Explorer で Lambda 関数を表示させます。
ここで、実行ボタン(横向き△のボタン)にマウスをホバーさせると『Invoke in the cloud』とあるので、これをクリックすることで、 aws 側の関数を呼び出すことができそうです。
やってみます。実行ボタンを押すと、
のような画面が表示されます。今回は payload に何も指定せず、そのまま『Remote Invoke』ボタンを押します。
するとこんな感じで応答が出力されました。CloudWatch ログにも実行したログが残ってますし、大丈夫そうですね。