Lambda Web Functionsをaws-sam-cliでデプロイする

Lambda Web Functionsをaws-sam-cliでデプロイする

# 導入文 aws-sam-cliがLambda Web Functionsに対応したので、実際にデプロイしてみました。ビルド設定からデプロイまでの手順を、実装例を交えて紹介します。
2026.10.28

こんばんは、情報システム室の夏目です。

本日、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によるビルド (トランスパイルとバンドル)にも対応しています。

https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/using-sam-cli-deploy.html#deploying-webfunctions

https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/using-sam-cli-deploy.html#deploying-webfunctions

ただし、 sam build コマンドによるビルドには1点注意が必要です。

The deployment package is always a .zip file archive built for the x86_64 architecture.

Web Functionは ARM64 アーキテクチャ上で動きます。

https://docs.aws.amazon.com/lambda/latest/dg/web-functions-configuration-architecture.html

そのため、Pure JS/TS なモジュールなら影響はないが、ネイティブモジュールを含む場合は動かないと思われます。
(これについてはIssueもPRも出ていなかったので、おそらく気づいてないのではないかと)

試してみる

SAMでWeb Functionのデプロイを試してみます。
aws-sam-cliを使ってビルドとパッケージングも行います。

コードの準備

デプロイするTSのコードやtsconfig.jsonなどを用意します。

src/index.ts
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,
});
tsconfig.json
{
  "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"]
}
package.json
{
  "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に記載します。

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 のままで問題ないです

他にも、設定せずデフォルト値を使っているプロパティが多いので、詳しくはこちらを見てください。

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

ビルド設定

sam build でビルドする場合、ビルド設定はリソース定義から算出されたり Metadata に記載したりします。

軽く解説すると次のようになります。

  • BuildMethod: esbuild
    • esbuildでビルドを行うための記述
  • Format: esm
    • package.jsonで type: module としているため
  • Target: es2024
    • tsconfig.jsonで target: es2024 としているため

他にも設定できるものはあるので、詳細は次のページを確認してください。

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

エンドポイントやリビジョンの論理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
    • ビルドの設定が記載されている
    • 故に、ビルドの最初に作られる

また生成されたテンプレートファイルは次のようになっています。

.aws-sam/build/template.yaml
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でデプロイしてみました。

何かのお役に立てたら幸いです。

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事