こんにちは!Dirbatoの社内技術横断支援組織Backbeatに所属している柴田です!
2026年10月12日、AWS Lambda に「Web Functions」という3つ目の形態が加わりました。 app.listen() した普通の Node.js の Web サーバを、アダプタなしでそのまま Lambda に載せられます。1つの実行環境で複数のリクエストを同時にさばき、課金されるのは CPU が実際に動いた時間だけ。「DB や外部 API を待っている時間はタダ」という触れ込みです。
そこで東京リージョンで、同じコード・同じ負荷を従来の Lambda と並べて流し、課金メトリクスから金額を出しました。 結果は、待つだけの API は従来の 1/35。ところが CPU だけを使う処理は 2.5 倍高く、SSR はほぼ互角でした。さらに、作りたての関数がバーストで 429 を連発する、環境が自動で増えて RDS の接続数が上限を超える、ログが 2 本・無期限で残るといった、設計に直結する挙動も観測しています。
後半では、検証で見えた Web Functions 固有の弱点を起点に、最近の情報漏洩の典型パターンに沿ったセキュリティ対策をまとめました。
免責
本記事は筆者個人の見解であり、所属組織の公式見解・開発体制・業務内容を示すものではありません。記事内の技術的表現は執筆時点(2026年10月)の実機検証に基づくものであり、特定の製品・サービスの性能・仕様を保証するものではありません。アカウントIDはマスク(123456789012)し、エンドポイントのドメインは記載していません。一部は実機観測値であり、公式記載と異なる場合があります。
要点サマリー(2026年10月時点の実測・結論先出し)
| # | 検証したこと | 結果 |
|---|---|---|
| 1 | 2 秒待つ API の課金 | ✅ 10 万件あたり $0.077。従来の Lambda($2.691)の 1/35 |
| 2 | SSR 相当(CPU 40ms+待ち 110ms)の課金 | ⚠️ $0.238 vs $0.234 でほぼ互角 |
| 3 | CPU だけを使う処理の課金 | 🚨 $0.261 vs $0.105。Web Functions が 2.5 倍高い(従来の Lambda の Arm 単価は推定) |
| 4 | 作りたての関数へのバースト | 🚨 1 環境に 2 件しか入れず、同時 30 件中 22 件が 429。約 40 秒で学習して 0 件に |
| 5 | 学習の持続 | ✅ 30 分以上アイドルで 0 台に戻っても、新しいリビジョンでも引き継がれた |
| 6 | 負荷停止後 | ⚠️ 環境は約 6 分残り、課金が続く。短いバーストでは生存時間の 92% がアイドル |
| 7 | コールドスタート | ⚠️ 1 件目が 約 +0.35〜0.45 秒。新リビジョンの 1 件目は毎回コールド |
| 8 | VPC+RDS | 🚨 環境が自動で 20 まで増え、RDS(上限 79 接続)が枯渇し成功率 55%。プールを絞ると 100% |
| 9 | ログ | 🚨 1 関数 2 ロググループ、どちらも既定で無期限保持 |
| 10 | 初めて使うときの上限 | ⚠️ 200 vCPU / 10,000 RPS(公式既定 2,000 / 100,000 の 1/10) |
ひとことで: 2 秒待つ API では、従来の Lambda の 1/35 の料金でした。LLM の応答を待つ API や薄い BFF に向いています。一方で CPU を使う処理では単価の高さが出ます。また、入口の認証・外向き通信の制限・ログの保持期間は、自分で設定しないと既定のままです(入口は常に公開、外向き通信は VPC の外、ログは無期限)。
Lambda Web Functions とは
Lambda は 3 つの形態になりました。
| 形態 | 動かし方 | 1 環境の同時処理 | 課金 |
|---|---|---|---|
| Event Functions(従来の Lambda) | ハンドラ関数 | 1 件 | 実行時間(待ちも含む) |
| Web Functions |
listen() する HTTP サーバ |
Lambda が動的に決める(上限の既定 64、設定範囲 1〜128) | CPU が動いた時間+メモリ×生存時間 |
| MicroVMs(2026-06 発表) | Dockerfile からイメージ | vCPU に比例 | vCPU+メモリ+スナップショット |
Web Functions の実行環境は 2 vCPU / 2 GB 固定、ランタイムは Node.js 24(Arm64)のみです。課金単価(東京)は、リクエスト $0.30/100 万件、使用中 vCPU $0.0000322421/秒、メモリ $0.0000042688/GB 秒です(バージニア北部より約 16% 高い)。メモリは「消費した量」が、リクエストの合間も含めて環境が生きている間ずっと課金されます(料金ページの記載: "billed for the memory it consumes, for as long as it runs, including time between requests")。
デプロイ手順や SSE、Next.js での動作、Lambda Web Adapter との性能比較、CloudFront OAC との組み合わせは、クラスメソッドさんの記事で丁寧に検証されています。料金の試算はサーバーワークスの記事が詳しいです。本記事はそれらが扱っていない 同じ負荷で並べた課金の実測・スケールの挙動・DB 接続・ログ・セキュリティ に絞りました。先行記事の皆さま、ありがとうございます。
- GAになった Lambda Web Functions を東京リージョンで試してみた
- Lambda Web Functions と Lambda Web Adapter で、アセット数多めの Next.js(SSR)ページの配信性能を比べてみた
- Lambda Web Functions を CloudFront OAC で保護すると、POST / PUT の x-amz-content-sha256 が不要になる
検証環境
| 項目 | 値 |
|---|---|
| リージョン | ap-northeast-1(東京) |
| ランタイム |
nodejs24.x(システムログ上は nodejs.web24.v14) |
| SDK | boto3 1.43.114(執筆時点で AWS CLI 2.34.27 は lambda-web 未対応だったため) |
| 検証アプリ | 依存ゼロの node:http。/io?ms=2000(待つだけ)、/cpu?ms=50(ビジーループ)、/mix(CPU 15→待ち 90→CPU 15→待ち 20→CPU 10ms) |
| 比較対象 | 従来の Lambda(arm64・1,024 MB・Function URL)に同じロジックを handler として実装 |
| 負荷 | 手元から依存ゼロの Node スクリプト。各 1 万件・同時 50 |
| 課金の算出 | Web Functions は EnvironmentCPUTime × vCPU 単価 + EnvironmentActiveTime × 実使用メモリ × GB 単価 + 件数。従来は Duration 合計 × 1 GB × GB 単価 + 件数 |
/mix は、AWS 公式の料金例にある SSR(150ms のうち CPU 40ms)を再現したものです。
検証1: 課金 ―― 待ちは 1/35、CPU は 2.5 倍
| 処理 | Web Functions CPU/件 | Web Functions 10 万件あたり | 従来の Lambda 10 万件あたり | 比 |
|---|---|---|---|---|
/io(2 秒待つ) |
3.0 ms | $0.077 | $2.691 | 1/35 |
/mix(SSR 相当) |
44.1 ms | $0.238 | $0.234 | 1.02 倍 |
/cpu(CPU 50ms) |
53.3 ms | $0.261 | $0.105 | 2.5 倍 |
単価の前提: 東京リージョンの公表値で計算しています(Web Functions の CPU・メモリはバージニア北部より約 16% 高く、リクエスト単価は同じ)。従来の Lambda の Arm 単価は料金ページの本文から取得できなかったため、x86 公表値($0.0000166667/GB 秒)の 80% と推定しています。Web Functions のメモリは実使用量の最大値(171〜197MB)で上限側に計算しました。
なぜ待つ処理は安いのか。 2 秒待つ API の CPU 時間は 1 件わずか 3ms でした。従来の Lambda は 2 秒ぶんを丸ごと課金します。
なぜ CPU だけの処理は高いのか。 Web Functions の vCPU 秒単価(東京 $0.0000322)は、従来の Lambda の 1 GB 秒単価($0.0000133)の約 2.4 倍です。待ち時間の節約が無い処理では、単価差がそのまま出ます。SSR のように CPU と待ちが混ざる処理では、2 つの効果がほぼ打ち消し合いました。
他の記事との関係: 料金の考え方は サーバーワークスの記事(東京単価での試算。10 秒待ちのチャット API で約 $68 → 約 $12)が詳しく、実運用の料金は クラスメソッドの記事(個人ブログを移行して 30 日換算 約 $5.8)が参考になります。本記事の数字は、同じコード・同じ負荷を 2 つの形態に流した実測です。
自分の処理で試算するなら
実測 3 件に合わせると、次の簡易モデルで差が 15% 程度に収まりました(メモリ料金は負荷後のアイドル時間で変わるため、厳密ではありません)。
Web Functions(1件)= (CPU時間 + 3.5ms) × $0.0000322421/秒 + $0.0000005(メモリ)+ $0.0000003(リクエスト)
従来の Lambda(1件)= (処理時間 + 12ms) × 1GB × $0.0000133334/GB秒 + $0.0000002(リクエスト)
検証2: 作りたての関数は 429 を連発する
Web Functions は 1 環境あたりの同時処理数をLambda 自身が負荷を見て動的に決めます(maxConcurrencyPerEnvironment は上限にすぎない、と公式にあります)。これを実測しました。
新しい関数に同時 30 件(環境上限 4)
| 回 | 開始からの時間 | 200 | 429 | 1 環境の最大同時処理 |
|---|---|---|---|---|
| 1 | 0 秒 | 8 | 22 | 2 |
| 2 | 約 7 秒 | 8 | 22 | 2 |
| 3 | 約 14 秒 | 8 | 22 | 2 |
| 4 | 約 40 秒 | 30 | 0 | 8 |
作りたての関数は 1 環境に 2 件しか入れません。 4 環境 × 2 件 = 8 件しか受けられず、残りが 429(Too Many Requests)になりました。約 40 秒後には 1 環境 8 件まで上がり、429 は消えています。
一度学習した関数は詰まらない
| 条件 | 429 | 1 環境の同時処理 |
|---|---|---|
| 学習済みの関数・30 分以上アイドル後(環境上限 4・同時 30) | 0 / 30 | 30 |
| 学習済みの関数の新しいリビジョン(同条件) | 0 / 30 | 30 |
| 学習済みの関数・環境上限なし・同時 300 | 0 / 300 | 最大 64(既定の上限) |
学習した同時処理数は、0 台に戻ったあとも新しいリビジョンでも引き継がれました。 429 が問題になるのは「新しく作った関数に、いきなりバーストが来る」ケースです。リリース直後にキャンペーンなどでアクセスが集中する場合は、事前に負荷をかけて慣らすか、環境上限に十分な余裕を持たせる必要があります。
CPU を使う処理では、学習しても 1 環境 1〜2 件のままでした(/cpu は 1 件、/mix は 2 件)。同時 50 件で環境上限 20 に当たり、/mix は 15% が 429 になっています。「1 環境で最大 128 件」の恩恵は、ほぼ待つだけの処理に限られます。
検証3: 負荷が止まっても 6 分残る
| 処理 | 負荷中の環境生存時間 | 負荷後の環境生存時間 | 負荷後の割合 |
|---|---|---|---|
/cpu(約 30 秒のバースト) |
604 秒 | 7,299 秒 | 92% |
/mix(約 40 秒のバースト) |
604 秒 | 7,345 秒 | 92% |
/io(約 7 分の負荷) |
3,496 秒 | 827 秒 | 19% |
負荷が止まってから最後のメトリクス記録まで、3 関数とも約 6 分でした。クラスメソッドの記事でも、本番ログで最後のリクエストから約 6 分で環境が終了しており(377 環境中 316 が 5〜7 分)、同じ挙動です。アイドル中も 1 環境あたり毎分 85〜110ms の CPU を消費しています。今回はメモリ使用量が 200MB 未満だったので金額は小さいですが、500MB 以上使うアプリでバーストが多いと無視できなくなります。
検証4: コールドスタートは +0.4 秒、新リビジョンは毎回
| アプリ | 1 件目(TTFB) | 2 件目以降 | サーバ側の初期化 |
|---|---|---|---|
| 依存ゼロ | 0.49〜0.60 秒(4 回) | 0.11〜0.22 秒 | 192〜259 ms |
| AWS SDK v3 を 4 つ読み込む(28MB) | 0.57〜0.78 秒(4 回) | 0.08〜0.26 秒 | 310〜425 ms |
(TTFB は手元から計測。接続 50〜150ms を含む)
依存を増やしても +0.1 秒程度でした。それより注意したいのは、最低台数を確保する設定が無いことと、新しいリビジョンに切り替えると次の 1 件目が毎回コールドになることです。デプロイのたびに最初の利用者が約 0.5 秒待ちます。
検証5: VPC+RDS ―― 環境が増えて RDS の接続数が上限を超える
egress network connector で VPC 内の RDS(db.t4g.micro、max_connections=79)につなぎ、/db?ms=500(DB で 0.5 秒待つ)に同時 100・3,000 件を流しました。
| 1 環境の接続プール | 成功率 | RDS 最大接続数 | 環境数 | 所要時間 | 応答 p50 / p90 |
|---|---|---|---|---|---|
| 10 本 | 🚨 55% | 70 | 20(上限) | 361 秒 | 0.54 / 5.0 秒 |
| 3 本 | ✅ 100% | 27 | 9 | 79 秒 | 2.4 / 4.0 秒 |
プール 10 本では、RDS が remaining connection slots are reserved for roles with the SUPERUSER attribute を返し、500 エラーが 664 件、通信エラーが 673 件出ました。
なぜこうなるか。 DB で 0.5 秒待つ処理でも、1 環境の同時処理は 8 件止まりで、Lambda は環境を上限の 20 まで増やしました。20 環境 × 10 本 = 最大 200 本を張ろうとして、上限 79 を超えたわけです。プールを絞ると、空き待ちが「I/O 待ち」とみなされて 1 環境に 27 件まで詰め込まれ、環境数も 9 に減りました。
設計の目安: 1環境の接続プール × maxEnvironments ≦ DB の max_connections
応答時間も守りたいなら、RDS Proxy で接続をまとめるか、DB を大きくする必要があります。
構築で引っかかったところ
| 項目 | 観測したこと |
|---|---|
| ツール | 執筆時点で aws-mcp と AWS CLI 2.34.27 は lambda-web を呼べず、boto3 1.43.114 で実施 |
| S3 のコード置き場 | Lambda サービスに s3:GetObject / s3:GetObjectVersion を許可するバケットポリシーと、バージョニングが必要 |
| egress connector | 作成時に AWSServiceRoleForLambda(サービスリンクロール)を要求。ACTIVE まで約 4 分半 |
| connector の ENI | ACTIVE 後も通信中も、検証 VPC の describe-network-interfaces からは列挙されなかった(存在しないことは示せていない) |
| デプロイ直後 | connector 付きの関数は数十秒間 409 Conflict を返した |
| MultiRegion | ホーム以外に 1 リージョン以上の指定が必須。connector を使えるのは HomeRegion のエンドポイントのみ(公式記載) |
| WebSocket |
Upgrade ヘッダは除去され、通常の 200 応答になる(101 は返らない) |
| 上限 |
GetWebAccountSettings は maxTotalArmVCpus=200 / maxTotalRateLimit=10000。長く使っているアカウントでもこの値だった |
後半: 情報漏洩を防ぐセキュリティ設計
ここからは、検証で触って分かった Web Functions の性質を、最近の情報漏洩の典型パターンに当てはめて対策を整理します。
| 漏洩の典型パターン | Web Functions で起きる場所 | 検証で見えた性質 |
|---|---|---|
| ① 公開設定のミス | 入口のエンドポイント | 入口は常にインターネット公開。PrivateLink 不可 |
| ② 認証情報の漏洩 | 環境変数・コード | 検証では DB パスワードを環境変数に入れた(検証用・本番不可) |
| ③ ログ経由の漏洩 | CloudWatch Logs | console.* が自動収集され、2 本・無期限で残る |
| ④ データの持ち出し | 外向き通信 | connector 無しでは公開 IPv4 宛てに直接出る。SG などの制限は効かない |
| ⑤ サプライチェーン攻撃 | npm の依存パッケージ | ランタイムは Node.js のみ=npm エコシステムに依存 |
| ⑥ 権限の過剰付与 | 実行ロール・デプロイ権限 | コード置き場にサービス向けバケットポリシーが必須 |
| ⑦ 費用攻撃(Denial of Wallet) | スケール | 環境は自動で増え、負荷後も約 6 分課金が続く |
推奨構成を先に示します。
① 入口:常に公開されるので、IamAuth と CloudFront で署名付きの呼び出しだけにする
Web Functions のエンドポイントは常にインターネットから届き、AWS PrivateLink で閉域にはできません。認証方式は 2 つです。
-
ApplicationManaged:誰でも呼べる。認証はアプリ任せ -
IamAuth:SigV4 署名が必要。呼び出し元にlambda:InvokeWebFunctionEndpointの権限が要る
本番では IamAuth + CloudFront(OAC)+ WAF を基本にします。リソースベースポリシーで CloudFront のサービスプリンシパルに呼び出しを許可し、aws:SourceArn で自分のディストリビューションに絞ります。こうすると、Lambda が用意したドメインを直接叩く未署名のリクエストは拒否されます。ただしドメイン自体はインターネットから届くので、呼び出し権限を持つ主体が署名すれば CloudFront を通らずに直接呼べます。lambda:InvokeWebFunctionEndpoint を渡す相手は CloudFront だけに絞ります。
Web Functions は公開扱いのリソースベースポリシー(Principal: "*" だけで絞り込みの無いもの)を ValidationException で拒否します。aws:SourceIp での絞り込みも「非公開」とはみなされません。設定ミスで全世界に公開してしまう事故を、サービス側で防ぐ仕組みです。一方、aws:PrincipalOrgID や aws:SourceArn などの信頼済み条件キーを固定値で付ければ、Principal が "*" でも非公開として許可されます。
あわせて確認したいことです。
-
組織として公開エンドポイントを禁止する:条件キー
lambda:Request/WebFunctionAuthTypeを使えば、SCP や IAM ポリシーでApplicationManagedのエンドポイント作成を Deny できます(公式)。手軽なaws lambda-web deployは既定でApplicationManagedを作るので、本番アカウントでは特に有効です -
ApplicationManagedを使う場合:CloudFront を経由しない直アクセスが WAF を素通りします。オリジン用のシークレットヘッダなどで「CloudFront 経由であること」をアプリ側で検証する -
CORS は自前:Lambda は CORS ヘッダを付けません。
Originを丸ごと反射せず、許可する Origin を明示する -
Hostヘッダを転送しない:CloudFront からはAllViewerExceptHostHeaderを使う(Hostを転送すると 404 になる、と公式にある)
公式に掲載されている SCP の例です。CreateWebFunction も対象に含めているのは、関数作成時に最初のエンドポイントも一緒に作られるためです。この SCP があると、aws lambda-web deploy は --auth-type IamAuth を付けない限り拒否されます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": [
"lambda:CreateWebFunction",
"lambda:CreateWebFunctionEndpoint",
"lambda:UpdateWebFunctionEndpoint"
],
"Resource": "*",
"Condition": {
"StringEquals": { "lambda:Request/WebFunctionAuthType": "ApplicationManaged" }
}
}
]
}
② 認証情報:環境変数に秘密を置かない
検証では、DB のパスワードを環境変数で渡しました。検証用の割り切りで、本番ではやってはいけない構成です。 環境変数はリビジョンの設定として残り、関数の設定を読める人なら誰でも見られます。
| 対策 | 内容 |
|---|---|
| Secrets Manager から実行時に取得 | 起動時に取得してメモリに保持する。private サブネットから使うなら、connector のサブネットに Secrets Manager の VPC エンドポイントが必要(NAT が無いと届かない) |
| RDS の IAM 認証 | パスワードを持たず、実行ロールで一時トークンを発行する |
| カスタマー管理キー(KMS) | Web Functions はコードと環境変数をカスタマー管理キーで暗号化できる。キーポリシーで復号できる人を絞る。なおキーを無効にしても、動いている環境はキャッシュで動き続け、即時の遮断にはならない(公式記載)。緊急時は rateLimit=0 で止める |
| 開発端末に長期のアクセスキーを置かない | CI は OIDC で一時認証。手作業の管理者操作は MFA 付きで短時間だけ昇格する |
最後の項目は、⑤のサプライチェーン攻撃への備えでもあります。
③ ログ:2 か所に無期限で残るので、保持期間・暗号化・保存先の国を先に決める
検証で分かったログの性質です。
-
console.*の出力はエージェント不要で自動的に CloudWatch Logs に送られる(JSON 化され、requestIdなどが付く) - 1 関数につき
<name>.localと集約先の 2 本ができ、どちらも保持期間は無期限 - 集約先は
.localより 9〜27 秒遅れて作られた。作成直後に保持期間を設定すると、片方が無期限のまま残る - 関数の削除直後にロググループを消したら、遅れて届いたログで再作成された
-
MultiRegionのエンドポイントでは、各リージョンのログがホームリージョンに集約される(公式記載)
ログに個人情報やトークンが 1 度でも出れば、2 か所に無期限で残り続けます。 対策は次のとおりです。
| 対策 | 内容 |
|---|---|
| ロググループを先に作る |
.local と集約先の両方を事前に作り、保持期間と KMS 暗号化を設定してから telemetryConfig で指定する |
| ログレベル |
applicationLogLevel で本番は INFO 以上に。デバッグ出力が本番に残らないようにする |
| 書かない | リクエストヘッダ(Authorization・Cookie)やリクエスト本文を丸ごと出さない |
| データ保護ポリシー | CloudWatch Logs のデータ保護で、メールアドレスやクレジットカード番号などをマスクする。設定前に取り込んだログはマスクされないので、ロググループの事前作成とセットで最初に入れる |
| 越境 |
MultiRegion は海外リージョンのログをホームリージョンへ、ホームが海外なら逆向きに集める。個人データを扱うなら、保存先の国を設計時に確認する |
| 撤去の順序 | 実行ロールを消してからロググループを消す |
④ 外向き通信:既定は「どこへでも出られる」
ここが一番見落としやすい点です。connector を付けない Web Functions は、VPC を通らずに公開 IPv4 宛てへ直接通信します(公式記載)。送信元 IP は Lambda の管理で、固定されません。つまり、
- 相手先の IP 許可リストには載せられない
- VPC のセキュリティグループや NACL、ルートテーブルによる宛先の制限は、connector 経由の通信にしか効かない(公式記載。connector 無しで宛先を絞る方法は、公式ドキュメントからは見つけられなかった)
アプリに SSRF(外部から指定された URL へサーバが取りに行く脆弱性)があったり、⑤のように悪意あるパッケージが紛れ込んだりした場合、ネットワーク側でデータの送り先を絞れないことになります。
機密データを扱う関数は、connector を付けて外向き通信を VPC に通します。 そのうえで、
- セキュリティグループの送信ルールで、宛先を DB や VPC エンドポイントに限定する
- インターネットに出る必要があるなら、NAT Gateway の手前に AWS Network Firewall や Route 53 Resolver DNS Firewall を置き、ドメイン単位で許可する
- アプリ側でも、ユーザー入力の URL を取りに行く処理は宛先を検証する
connector を使えるのは HomeRegion のエンドポイントだけです。「グローバル配信」と「外向き通信の制御」は同時に取れない、という設計上のトレードオフがあります。
⑤ サプライチェーン:npm に依存する前提で守る
Web Functions のランタイムは Node.js 24 だけです。2025 年 9 月には、自己増殖する npm ワーム「Shai-Hulud」が 500 以上のパッケージを汚染し、開発者の環境から GitHub トークンや AWS などのクラウド認証キーを盗み出しました(米 CISA が注意喚起)。
| 対策 | 内容 |
|---|---|
| ロックファイルで固定 |
package-lock.json をコミットし、ビルドは npm ci。依存のバージョンを勝手に上げない |
| インストール時のスクリプトを止める |
npm ci --ignore-scripts(本検証でもこれで pg と AWS SDK を入れた)。必要なものだけ個別に許可する |
| 依存を減らす | 本検証では依存ゼロのアプリで 1 件目が 0.56 秒、SDK 4 つで 0.68 秒。依存を増やすと、起動が遅くなり、攻撃されうるパッケージも増える |
| ビルド環境と実行環境の認証情報を分ける | CI のトークンは OIDC の一時認証。実行ロールに CI の権限を持たせない |
| 監視 |
npm audit や依存関係の更新通知を CI に組み込み、侵害が報じられたパッケージをロックファイルから検索できるようにしておく |
⑥ 権限:コード置き場と実行ロールを絞る
| 対象 | 対策 |
|---|---|
| コード置き場の S3 | Lambda サービスへの読み取り許可は aws:SourceAccount で自アカウントに限定する。ブロックパブリックアクセスを有効化。書き込める人を絞る(ここに置いたコードがそのまま本番で動く) |
| 実行ロール | ログ書き込みと、アプリが本当に使う API だけ。ロググループの ARN まで絞る。ただし集約先に加えて <name>.local にも書き込み権限が要り、.local に書けないリージョンのログは届かない(公式記載) |
| デプロイ権限 |
CreateWebFunctionRevision と UpdateWebFunctionEndpoint(トラフィックの切り替え)を持つ人=本番を書き換えられる人。CI のロールに限定する |
| ロール作成 | 開発者がロールを作る場合は、権限境界(permissions boundary)を必須にして、作ったロールで権限昇格できないようにする |
⑦ 費用攻撃:環境数とリクエスト数の上限、緊急停止の手順を最初に設定する
Web Functions は環境を自動で増やし、負荷が止まっても約 6 分課金が続きます。大量のリクエストを送りつけて請求額を膨らませる攻撃(Denial of Wallet)への備えです。
| 対策 | 内容 |
|---|---|
maxEnvironments |
環境数の上限。DB の接続数の計算(検証5)にも使う |
rateLimit |
1 秒あたりのリクエスト上限。超えた分は 429 |
| キルスイッチ |
rateLimit を 0 にすると全リクエストを遮断できる(503 になる)。手順を Runbook に書いておく |
| WAF | レート制限ルールと Bot 対策を CloudFront 側で |
| 予算アラート | AWS Budgets はサービスやタグでフィルタできる。フィルタを付けないと対象がアカウント全体に広がり、小さなサービスの異常は埋もれて検知しにくい |
| メトリクス |
HTTPResponseStatusClass4XX / 5XX、AWS/Lambda/Web/Usage 名前空間のスロットリング系メトリクス(EndpointRequestThrottles など)にアラームを張る。これらは事象が無い期間はデータ点が出ない(sparse)ので、欠損データは「正常」扱い(notBreaching)にする |
チェックリスト
| # | 項目 |
|---|---|
| 1 | エンドポイントは IamAuth、前段に CloudFront(OAC)+ WAF。SCP で ApplicationManaged を禁止 |
| 2 | リソースベースポリシーは aws:SourceArn でディストリビューションに限定 |
| 3 | 秘密情報は環境変数に置かず Secrets Manager / IAM 認証。環境変数は KMS で暗号化 |
| 4 | ロググループは事前作成(.local も)、保持期間・KMS・データ保護ポリシーを設定 |
| 5 | 機密データを扱う関数は connector で外向き通信を VPC に通し、宛先を限定 |
| 6 |
npm ci --ignore-scripts、ロックファイル固定、依存を最小に |
| 7 | 実行ロール・デプロイ権限・コード置き場の S3 を最小権限に |
| 8 |
maxEnvironments / rateLimit を設定し、キルスイッチ(rateLimit=0)を Runbook に |
| 9 | DB 接続は「プール × maxEnvironments ≦ max_connections」、足りなければ RDS Proxy |
| 10 | 新しい関数を公開する前に、想定ピークの負荷をかけて同時処理数を学習させる |
まとめ:新規で選ぶなら
| ケース | 選択 | 理由 |
|---|---|---|
| LLM 呼び出し API・薄い BFF | ✅ Web Functions | 待ち時間が課金されず、従来の 1/35 |
| SSR の Web アプリ | ⚖️ どちらでも | 課金は互角。運用の軽さと 0 台まで縮むことで選ぶ |
| RDS を使う Web アプリ | ⚠️ 条件付き | 接続数の設計が必須。超えるなら RDS Proxy |
| CPU を使い続ける処理 | ❌ Fargate / 従来の Lambda | vCPU 秒単価が約 2.4 倍(東京) |
| 閉域必須・WebSocket・Node.js 以外 | ❌ Fargate | 入口は PrivateLink 不可、WebSocket 不可、Node.js のみ |
LLM の応答を待つ API では、料金が 1 桁以上下がります。一方で、入口が公開・外向き通信は VPC の外・ログが無期限という初期状態のまま本番に出すと、情報漏洩の典型パターンにそのまま当てはまります。本番に出す前に、上のチェックリスト 10 項目を設定することをおすすめします。
参考
- Announcing AWS Lambda Web Functions(AWS Blog)
- Scaling behavior for Lambda Web Functions
- Configuring networking for AWS Lambda Web Functions
- Lambda Web Function permissions
- Lambda Web Function endpoint access control
- Encryption at rest for Web Functions
- Masking sensitive log data(CloudWatch Logs データ保護)
- Web Function logs in Amazon CloudWatch Logs
- Using CloudWatch metrics with Lambda Web Functions
- Lambda quotas
- AWS Lambda 料金
- AWS Lambda Web Functions で LLM の待ち時間は課金されない?(サーバーワークス, 2026-10-21)
- 個人ブログを Lambda Web Functions + CloudFront に移行して、実際の料金を確認してみた(クラスメソッド, 2026-10-27)
- Widespread Supply Chain Compromise Impacting npm Ecosystem(CISA, 2025-09-23)
