
Lambda Web Functionsをaws-sam-cliでデプロイする
こんばんは、情報システム室の夏目です。
本日、Severless Application ModelでLambda Web Functionsをデプロイできることに気づきました。
なので今回はaws-sam-cliでLambda Web Functionsをデプロイしてみます。
aws-sam-cliのLambda Web Functions対応
- aws-sam-cli: v1.170.0
ローカルコードのLambda Web Functionにaws-sam-cliが対応したのが10/23 (金) にリリースされたv1.170.0からです。
sam build コマンドを使ってesbuildによるビルド (トランスパイルとバンドル)にも対応しています。
ただし、 sam build コマンドによるビルドには1点注意が必要です。
The deployment package is always a .zip file archive built for the x86_64 architecture.
Web Functionは ARM64 アーキテクチャ上で動きます。
そのため、Pure JS/TS なモジュールなら影響はないが、ネイティブモジュールを含む場合は動かないと思われます。
(これについてはIssueもPRも出ていなかったので、おそらく気づいてないのではないかと)
試してみる
SAMでWeb Functionのデプロイを試してみます。
aws-sam-cliを使ってビルドとパッケージングも行います。
コードの準備
デプロイするTSのコードやtsconfig.jsonなどを用意します。
import { serve } from "@hono/node-server";
import { Hono } from "hono";
const app = new Hono();
app.get("/", (c) => c.json({ ok: true }));
const address = process.env.AWS_LAMBDA_HTTP_ENDPOINT ?? "0.0.0.0:3000";
const [hostname, port] = address.split(":");
serve({
fetch: app.fetch,
port: Number(port),
hostname,
});
{
"compilerOptions": {
"target": "es2024",
"lib": ["es2024"],
"types": ["node"],
"module": "preserve",
"moduleResolution": "bundler",
"strict": true,
"noEmit": true,
"allowImportingTsExtensions": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true
},
"include": ["./src"]
}
{
"name": "trial-sam-deploy-01",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "sam build --template-file sam.yml"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "module",
"dependencies": {
"@hono/node-server": "^2.1.5",
"hono": "^4.13.14"
},
"devDependencies": {
"@types/node": "^26.6.5",
"esbuild": "^0.28.2"
}
}
今回はこのように実装しています。
SAMのテンプレートを書く
SAMのテンプレートをsam.ymlに記載します。
Transform: AWS::Serverless-2016-10-31
Resources:
WebFunction:
Type: AWS::Serverless::WebFunction
Properties:
AuthType: ApplicationManaged # required
CodeUri: . # required
Runtime: nodejs24.x # required
EntryPoint: src/index.ts
Metadata:
BuildMethod: esbuild
BuildProperties:
Format: esm
Target: es2024
Minify: true
Outputs:
EndpointUrl:
Value: !Sub https://${WebFunctionEndpoint.DomainName}
SAMでWeb Functionを定義するには AWS::Serverless::WebFunction を使用します。
Properties の設定としては今回最低限必要なものになっています。
今ディレクトリの構造は次のようになっています。
./
├── package.json
├── sam.yml
├── src/
│ └── index.ts
└── tsconfig.json
aws-sam-cliでビルドとパッケージングまで行うため CodeUri と EntryPoint は次のようにしています。
CodeUri: .- package.jsonやtsconfig.jsonをsam.ymlと同じプロジェクトルートに置いているので、今回はこうしています
- これはテンプレートファイルと同じディレクトリという意味です
EntryPoint: src/index.ts- CodeUri で指定したディレクトリからの相対パスで指定します
- aws-sam-cliでビルドとパッケージングを行うのでここは
*.tsのままで問題ないです
他にも、設定せずデフォルト値を使っているプロパティが多いので、詳しくはこちらを見てください。
ビルド設定
sam build でビルドする場合、ビルド設定はリソース定義から算出されたり Metadata に記載したりします。
軽く解説すると次のようになります。
BuildMethod: esbuild- esbuildでビルドを行うための記述
Format: esm- package.jsonで
type: moduleとしているため
- package.jsonで
Target: es2024- tsconfig.jsonで
target: es2024としているため
- tsconfig.jsonで
他にも設定できるものはあるので、詳細は次のページを確認してください。
エンドポイントやリビジョンの論理ID
SAMではWeb Functionのエンドポイントやリビジョンの論理IDは Type: AWS::Serverless::WebFunction リソースの論理IDの末尾に Endpoint や Revision 付けたものになります。
(今回の例ならエンドポイントは WebFunctionEndpoint 、 リビジョンは WebFunctionRevision となる)
そのため、エンドポイントのURLを取得する部分で !Sub https://${WebFunctionEndpoint.DomainName} と書いています。
aws-sam-cliでビルドする
$ npm run build
> trial-sam-deploy-01@1.0.0 build
> sam build --template-file sam.yml
Building codeuri: /trial-sam-deploy-01 runtime: nodejs24.x architecture: x86_64 functions: WebFunction
Running NodejsNpmEsbuildBuilder:CopySource
Running NodejsNpmEsbuildBuilder:NpmInstall
Running NodejsNpmEsbuildBuilder:EsbuildBundle
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
package.jsonに "build": "sam build --template-file sam.yml" と記載しているので npm run build でビルドを行います。
自分の環境では直接 sam build を実行するとesbuildが見つからないとエラーが出たのでpackage.jsonに書いて npm run で呼び出す形になりました。
ビルドに成功すると .aws-sam/ は次のようになっています。
.aws-sam/
├── build/
│ ├── template.yaml
│ └── WebFunction/
│ └── index.js
└── build.toml
.aws-sam/build/template.yaml- ビルド後のアーティファクトも反映したSAMのテンプレートファイル
.aws-sam/build/WebFuntion/index.js- トランスパイルとバンドルした結果のファイル
.aws-sam/build.toml- ビルドの設定が記載されている
- 故に、ビルドの最初に作られる
また生成されたテンプレートファイルは次のようになっています。
Transform: AWS::Serverless-2016-10-31
Resources:
WebFunction:
Type: AWS::Serverless::WebFunction
Properties:
AuthType: ApplicationManaged
CodeUri: WebFunction
Runtime: nodejs24.x
EntryPoint: index.js
Metadata:
BuildMethod: esbuild
BuildProperties:
Format: esm
Minify: true
Target: es2024
SamResourceId: WebFunction
Outputs:
EndpointUrl:
Value:
Fn::Sub: https://${WebFunctionEndpoint.DomainName}
CodeUri と EntryPoint が更新されています。
デプロイする
今回自分は次のコマンドでデプロイを行いました。
$ sam deploy \
--template-file .aws-sam/build/template.yaml \
--resolve-s3 \
--stack-name trial-sam-deploy \
--capabilities CAPABILITY_IAM
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-fjh3ebmiqowg
Auto resolution of buckets can be turned off by setting resolve_s3=False
To use a specific S3 bucket, set --s3-bucket=<bucket_name>
Above settings can be stored in samconfig.toml
Looking for the Lambda Web Function code bucket of stack trial-sam-deploy
Creating the required resources...
Successfully created!
Lambda Web Function code bucket: trial-sam-deploy-5ca11996-webfunctionco-codebucket-pwhof35zu37d
Uploading to d50e8b3c5000bb7160d4e8450667b947 15686 / 15686 (100.00%)
Deploying with following values
===============================
Stack name : trial-sam-deploy
Region : ap-northeast-1
Confirm changeset : False
Disable rollback : False
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-fjh3ebmiqowg
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
...... (中略) ......
CREATE_COMPLETE AWS::CloudFormation::Stack trial-sam-deploy -
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CloudFormation outputs from deployed stack
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Key EndpointUrl
Description -
Value https://70yv97klmzq882ny.bhb.lambda-web.ap-northeast-1.on.aws
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - trial-sam-deploy in ap-northeast-1
無事にデプロイできました。
curlで叩いてみます。
$ curl https://70yv97klmzq882ny.bhb.lambda-web.ap-northeast-1.on.aws
{"ok":true}
動きました。
sam deploy --resolve-s3
--resolve-s3 というオプションを使うことでデプロイ用のS3 Bucketを自動的に用意します。
Bucketがなければ作成し、あれば使います。
もちろん次のようにすれば使用するS3 Bucketを自分で指定することもできます。
$ sam package \
--s3-bucket "<bucket name>" \
--template-file .aws-sam/build/template.yaml \
--output-template-file packaged-template.yaml
$ sam deploy \
--template-file packaged-template.yaml \
--stack-name trial-sam-deploy \
--capabilities CAPABILITY_IAM
ただ、Web Functionのデプロイに使用するS3 Bucketではバージョニングの設定をして、AWS Lambdaが s3:GetObject と s3:GetObjectVersion できるようにBucket Policyを設定をする必要があります。
今回はそこの手間を省くために --resolve-s3 を使用しました。
まとめ
以上、Lambda Web FunctionをServerless Application Modelとaws-sam-cliでデプロイしてみました。
何かのお役に立てたら幸いです。








