リリース前のAWS Lambda Web Functions(lambda-web)の仕組みを公開ソースから読み解いてみた
はじめに
2026年10月1日、botocore と AWS CLI v2 に AWS Lambda Web Functions(lambda-web)が追加されました(botocore のコミット f19f55e01)。
この記事では、公開リポジトリのソースを読み、リソース構成、デプロイの仕組み、エンドポイントの公開方式、CloudFront と IAM の定義を整理しました。
公開されている情報と現在の状態
botocore 1.43.107(2026年10月1日)の changelog には、次の記述があります。
Lambda Web Functions GA launch. Lambda Web Functions enable customers to run web applications and API backends
翌日の botocore 1.43.108(2026年10月2日)では、次の更新が入りました。
Documentation update for AWS Lambda Web Functions, clarifies that the LambdaWeb APIs are experimental and not yet available to external customers.
AWS CLI 2.37.9 の changelog にも、同じ文があります。
サービスモデル service-2.json のサービス説明は、現在次の文で始まります。
The AWS Lambda Web Functions APIs (LambdaWeb namespace) are experimental and for internal AWS use only. They are not yet available to external customers.
10月1日のコミット f19f55e01 から10月2日の 3d76b4622 までの差分は、service-2.json 1ファイルの21行の入れ替えです。各オペレーションの説明とサービス説明に、同じ注記が加わりました。
"GA launch" と "experimental ... not yet available" のどちらが実態かは、公開ソースからは判断できません。
SDK には、JavaScript、Go、Java、Rust、Ruby、PHP、.NET、C++ の8言語のクライアントが追加されています。JavaScript SDK のコミットも、botocore と同じく、10月1日の GA launch と10月2日の experimental 注記の2段階でした。
読み取ったのは botocore 6197e54b7(1.43.108)と aws-cli 72c21cc2b(2.37.9)時点のソースで、主な参照先は次のとおりです。
- botocore: service-2.json、10月2日の変更は 3d76b4622
- aws-cli: lambdaweb、deploy.rst
- aws-sdk-js-v3: client-lambda-web
- aws-sdk-go-v2: lambda-web.json
仕組み
Web Function、Revision、エンドポイント
出典は botocore の botocore/data/lambda-web/2025-03-07/service-2.json です。
リソースは3層です。最上位の Web Function(WebFunction)の下に、コードと設定を持つ不変の Revision(WebFunctionRevision)と、WebFunctionEndpoint が付きます。WebFunctionEndpoint は、関数を HTTPS で公開する URL を持つリソースで、クライアントはこの URL にリクエストを送ります。以降、WebFunctionEndpoint は「エンドポイント」と書きます。
3種類それぞれに作成・取得・一覧・削除の API がありますが、更新 API があるのはエンドポイント(UpdateWebFunctionEndpoint)だけです。コードや設定を変えるときは、新しい Revision を作ってエンドポイントの向き先を切り替えます。
CreateWebFunction が成功したときのステータスは 202 です。revisionConfig と endpointConfig を渡すと、初期 Revision とエンドポイントも同時に作られます。モデルの説明には "You don't need separate permissions for the initial revision or endpoint." とあります。ただし、IAM の定義では CreateWebFunction に、必要なアクションとして iam:PassRole と lambda:PassNetworkConnector が付いています(後述)。DeleteWebFunction は、Revision とエンドポイントをまとめて削除します。
コードの置き場所は S3(bucket、key、任意の versionId)だけです。モデル全体を検索しても、コンテナイメージ、Docker、ハンドラー、エントリーポイント、アーキテクチャに相当する項目はありませんでした。
Node.js アプリから見た実行モデル
この節の出典は公式ドキュメントではなく、aws lambda-web deploy --hello-world で生成される README.md と AGENTS.md の雛形です。
Lambda 固有のアダプターやラッパーを用意したりハンドラーを書き換えたりしなくても、ポートで待ち受ける標準的な Node.js アプリをデプロイできます。サーバーは RUNTIME_HTTP_PORT(3000)で待ち受けます。別のポートで待ち受けても Active にはなりますが、リクエストには HTTP 502 を返します。トラフィックに応じてスケールし、アイドル時はゼロまでスケールインします。レスポンスはアプリが書き込むたびにストリーミングされ、streamifyResponse のラッパーも不要です。
アーキテクチャは arm64 で、設定では変えられません。ネイティブバイナリを含む依存パッケージには arm64 版が必要です。
従来のハンドラー型は "Lambda Event Functions" と呼ばれています。雛形によると、Web Functions のプロジェクトには、エクスポートされたハンドラー、event / context 引数、API Gateway、Function URL、アダプターがありません。SAM、CDK、aws lambda コマンドの管理対象でもないとされています。
新規作成時の既定ランタイムは、CLI の定数で nodejs24.x と定められています。雛形には、このランタイムは型を除去して TypeScript を直接実行し、enum のようにコード生成が必要な機能を使う場合はトランスパイルが必要と書かれています。
Revision の設定項目
CreateWebFunction の revisionConfig では、buildConfig と serviceConfig が必須です。
| 項目 | 範囲・既定 |
|---|---|
| buildConfig.codeConfig.s3Object | bucket は3〜63文字、key は1〜1024文字、versionId は任意 |
| buildConfig.runtimeConfig.runtime | 文字列(説明の例は Node.js のランタイム識別子) |
| serviceConfig.executionRoleArn | 必須 |
| serviceConfig.timeoutSeconds | 3〜900、既定30 |
| serviceConfig.maxConcurrencyPerEnvironment | 1〜128、既定64 |
| serviceConfig.environmentVariables | 値は sensitive 扱い |
| serviceConfig.telemetryConfig.loggingConfig | logGroup の既定は /aws/lambda/web/{functionName}。アプリケーションログとシステムログのレベルの既定は、どちらも INFO |
| kmsKeyArn(revisionConfig 直下) | Revision のコードと環境変数の暗号化に使う KMS キー |
Revision の状態は、ビルド中の Pending、Active、Failed のいずれかです。
aws lambda-web deploy の流れ
出典は aws-cli の awscli/customizations/lambdaweb と awscli/examples/lambda-web/deploy.rst です。AWS CLI 2.37.8 の changelog には、aws lambda-web deploy の追加が書かれています。このコマンドは、ローカルの HTTP アプリケーションから Web Function を作成・更新します。
作成
スターターを生成してデプロイするには --hello-world を付けます。既存の HTTP サーバーから作る場合は、--code にディレクトリを渡し、確認プロンプトを --create で省略します。
aws lambda-web deploy --name my-app --hello-world
aws lambda-web deploy --name my-app --code ./app --create
次の出力例の識別子は、ドキュメントに架空のものと明記されています。
https://a1b2c3d4e5.x9y.lambda-web.us-east-1.on.aws
Console: https://us-east-1.console.aws.amazon.com/lambda/home#/web-functions/my-app
既存の Web Function がない場合、deploy.py は次の順序で処理します。
- 関数名と --code を検証する。--code はディレクトリに限られ、ビルド済みの .zip を渡すと、
create-web-functionとcreate-web-function-revisionを案内するエラーになる - STS の GetCallerIdentity でアカウント ID を取得する
- GetWebFunction で存在を確認する。なければ作成処理に進み、--hello-world と --create のどちらもなければ確認プロンプトが出る(標準入力が端末でなければ拒否される)
- エントリーファイルを解決して ZIP を作る。ZIP の上限は512MBで、超えると CLI はアップロードせずエラーで終了する
- S3 バケットを確認し、なければ作成する
- 実行ロールを確認し、なければ作成する
- ZIP を S3 にアップロードする
- CreateWebFunction を呼ぶ。ロール作成直後は IAM の反映待ちでリトライする
- --no-wait を付けなければ、エンドポイントが Active になるまで待ち(既定の待機は600秒)、URL を標準出力に出す
CLI が作る実行ロールの名前は、関数名が47文字以内なら awscli-lambdaweb-<関数名> です(それより長いと関数名が切り詰められ、末尾にハッシュが付きます)。S3 バケットの名前は awscli-lambdaweb-<アカウントID>-<リージョン>-an です。既存のロールとバケットは、それぞれ --execution-role-arn と --bucket-name で指定できます。CLI が設定する内容を次に示します。
CLI が作る実行ロールとバケットの設定
実行ロールの信頼ポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
実行ロールのインラインポリシー awscli-lambdaweb-logs
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
S3 バケットのポリシー(バケットのバージョニングも有効化されます)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "HttpsOnly",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::<bucket>",
"arn:aws:s3:::<bucket>/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
},
{
"Sid": "AllowLambdaServiceAccess",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::<bucket>/*",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "<account-id>"
}
}
}
]
}
エントリーファイルの決まり方
エントリーファイルは、--entry-point があればそれを使います。なければ package.json の main(ファイルが存在する場合)、次に exports の「.」エクスポートを調べます。それでも決まらなければ、次の順に探します。
index.js → index.mjs → index.cjs
server.js → server.mjs → server.cjs
dist/index.js → dist/server.js
build/index.js → build/server.js
雛形によると、ランタイムは既定で index.js を読み、package.json は読みません。決まったエントリーが index.js 以外のときは、index.js のラッパーが ZIP に加わります。CJS と ESM のどちらのプロジェクトでも動くように、ラッパーは動的 import() でエントリーを読み込みます。AWS_LAMBDA_NODEJS_ENTRYPOINT を自分で設定した場合、ラッパーは加わりません。この環境変数と --entry-point を併用するとエラーになります。
deploy は --code のディレクトリを ZIP にするだけで、npm install、バンドル、コンパイルは行いません。node_modules を含めるには、--code にプロジェクトルート(.)を渡します。TypeScript を dist/ にビルドするプロジェクトでも同様で、--code には ./dist ではなくプロジェクトルートを渡し、--entry-point で dist/index.js を指定します(deploy.rst の Example 8)。
シンボリックリンクは辿られず、スキップされます。雛形によると、pnpm や workspace のプロジェクトでは、npm install で実ファイルを配置するか、pnpm の node-linker=hoisted を設定します。
既定の除外対象には、次のようなファイルがあります。
.git/ .aws/ .ssh/ .env .env.* *.pem *.key id_rsa* .npmrc .netrc
一方、次の隠しディレクトリは既定で含まれます。
.next .nuxt .svelte-kit .output .prisma .yarn
2回目以降の更新
既存の Web Function に同じ --name で実行すると、最新の Revision を取得し、設定を引き継いで CreateWebFunctionRevision を呼びます。
aws lambda-web deploy --name my-app --code ./app
--code を省略すると前の Revision の S3 オブジェクトを再利用するので、設定だけを変えた Revision ができます。環境変数は --env で追加・上書きし、--unset-env で削除します。
Revision が Active になると、deploy は対象のエンドポイントを選びます。--endpoint-name があればそのエンドポイント、なければ LatestRevision のエンドポイント、それもなければ先頭のエンドポイントです。選んだエンドポイントの扱いは、状態によって変わります。
- LatestRevision のエンドポイントは自動で追従するので、deploy は更新しません
- Disabled のエンドポイントは、新しい Revision に重み100で付け替えます
- 重みが複数の Revision に分割されているエンドポイントは変更しません。分割を置き換えるときは、
aws lambda-web update-web-function-endpointを使うよう案内します
--endpoint-name に存在しない名前を渡すと、確認のうえで新しいエンドポイントを作ります。エンドポイントが1つもなく名前も指定しないときは、Revision だけをデプロイし、エンドポイントは作りません。
エンドポイントの公開方式
出典は、サービスモデルと、CLI のコメントおよびバリデーション処理です。
| 項目 | 取りうる値・範囲 |
|---|---|
| endpointType | HomeRegion(関数を作ったリージョンで配信)、MultiRegion(選んだリージョンに複製し、最寄りのリージョンへルーティング)、PerRegion(リージョンごとに別のエンドポイント) |
| regions | MultiRegion と PerRegion で必須。ホームリージョン以外のリージョンを少なくとも1つ指定する |
| authType | ApplicationManaged(関数側で認可)、IamAuth(Lambda が AWS SigV4 と IAM で認可) |
| autoDeploymentMode | LatestRevision(最新の Revision に自動で追従)、Disabled(明示的に変えるまで固定。モデルの既定) |
| revisionWeights | 1〜2要素。weight は1〜100 |
| scalingConfig.maxEnvironments | 2〜10000(既定なし) |
| throttleConfig.rateLimit | 0、100〜1000(100刻み)、2000〜10000(1000刻み)。アカウントの上限も適用される |
revisionWeights は、モデルでは canary や blue-green デプロイのトラフィック分割用と説明されています。
autoDeploymentMode の組み合わせには、CLI 側に次の制約があります。
- LatestRevision は revisionWeights を渡せず、HomeRegion のエンドポイントだけで使える
- Disabled は revisionWeights が必要
- MultiRegion と PerRegion は Disabled のみ
deploy の既定は、エンドポイント名「dev」、HomeRegion、ApplicationManaged、LatestRevision です。ApplicationManaged では認可が関数側に任されます。Lambda が AWS SigV4 と IAM で認可するのは IamAuth のときです。
エンドポイントでトラフィックを受けている Revision は、DeleteWebFunctionRevision で削除できません。
CloudFront のサポート
Lambda Web Functions を最初に追加した botocore のコミット f19f55e01 では、cloudfront のモデルにも変更が入りました。Origin Access Control(OAC)の署名動作に、always-amz-auth が加わりました。
モデルの説明によると、CloudFront は Amazon の認証ヘッダーですべてのオリジンリクエストに署名し、ビューアーのリクエストに Authorization ヘッダーがあればオリジンへ転送します。always-amz-auth は Lambda-Web オリジン専用です("This value is only valid with Lambda-Web origins.")。ビューアーの Authorization ヘッダーを転送するには、そのヘッダーをキャッシュポリシーに追加する必要があるという警告も付いています。CloudFront に新しいオペレーションは加わっていません。
IamAuth のエンドポイントは AWS SigV4 と IAM で認可され、always-amz-auth は CloudFront がオリジンリクエストに署名する動作です。この2点から、IamAuth のエンドポイントを CloudFront の背後に置く構成が想定されているとみられます。ただし、オリジンの指定方法はモデルからは分かりません。
IAM の定義
出典は aws-sdk-go-v2 の codegen/sdk-codegen/aws-models/lambda-web.json です。ARN の名前空間は lambda で、リソースの ARN テンプレートは次の3つです。
web-function/{functionName}
web-function/{functionName}/endpoint/{endpointName}
web-function/{functionName}/revision/{revisionId}
条件キーは2つあります。
lambda:Request/WebFunctionAuthType: リクエストに指定された認証方式でアクセスを絞ります。CreateWebFunction、CreateWebFunctionEndpoint、UpdateWebFunctionEndpoint に付いていますlambda:Resource/WebFunctionAuthType: エンドポイントに設定された認証方式でアクセスを絞ります。InvokeWebFunctionEndpoint、UpdateWebFunctionEndpoint、DeleteWebFunctionEndpoint、GetWebFunctionEndpoint に付いています
InvokeWebFunctionEndpoint は条件キーの説明にだけ登場し、サービスモデルのオペレーションにはありません。IamAuth のエンドポイントを呼び出す IAM アクションとみられます。
CreateWebFunction と CreateWebFunctionRevision には、requiredActions として iam:PassRole と lambda:PassNetworkConnector が付いています。lambda:PassNetworkConnector に対応する項目は、サービスモデルの入出力に見当たりません。
公開後に確認したいこと
VPC 接続については、3つの情報源で扱いが揃っていません。
- aws lambda-web deploy のヘルプ(args.py の DESCRIPTION)は、VPC への接続を個別の API コマンドで行うよう案内しています。原文は "such as weighted revision routing or connecting a Web Function to a VPC, use the aws lambda-web commands for specific API operations" です
- サービスモデルには、「vpc」「subnet」「securitygroup」「networkconnector」に相当する語がありません
- IAM の定義には、lambda:PassNetworkConnector があります
ほかに、公開ソースから確認できなかった項目は次のとおりです。
- クォータの実際の値。GetWebAccountSettings は、maxTotalArmVCpus、maxTotalRateLimit、maxRevisionsPerFunction、maxEndpointsPerFunction のクォータと、functionCount の使用量を返しますが、値はモデルにありません
- 対応するランタイムの一覧。runtime はモデル上、自由な文字列で、CLI の既定とエントリーの解決は Node.js 前提です
- 料金
- 公式ドキュメントとの照合。IAM の Service Authorization Reference と、実行モデルの記述(ポート3000、ゼロスケール、ストリーミング、502)が対象です
まとめ
Lambda Web Functions は、公開ソースから読む限り、ポートで待ち受ける Node.js の HTTP サーバーをハンドラーやアダプターなしで載せ、aws lambda-web deploy の 1 コマンドで S3 バケット、実行ロール、関数、エンドポイントまで作る仕組みでした。
CloudFront の OAC には、Lambda-Web オリジン専用の always-amz-auth も加わっています。
全体として、軽量なフレームワークで書いた Node.js の HTTP サーバーを、サーバーレスで動かす用途に向いていそうです。
ただし botocore の注記では、API は実験的で外部顧客にはまだ提供されていません。VPC 接続の仕様や料金も現時点では不明ですが、正式リリースを心待ちにしたいと思います。








