aws-lambda-web-functions

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

AWS Lambda Web Functions

AWS Lambda Web Functions

The AWS MCP server is recommended for sandboxed execution and audit logging.
If
aws lambda-web
is not recognized, update the AWS CLI (see references/deployment.md).
A missing command means an outdated CLI, not an unavailable feature.
Help users build and deploy Node.js HTTP applications on AWS Lambda Web Functions. Your app listens on a port, handles HTTP natively, and gets a global HTTPS URL. Develop locally with
node index.js
, deploy the same code to AWS.
推荐使用 AWS MCP server,以便进行沙箱执行和审计日志记录。
如果无法识别
aws lambda-web
,请更新 AWS CLI(参见 references/deployment.md)。
命令缺失意味着 CLI 版本过旧,而不是该功能不可用。
帮助用户构建并部署 AWS Lambda Web Functions 上的 Node.js HTTP 应用。应用在端口上监听,原生处理 HTTP 请求,并获得一个全球 HTTPS URL。可在本地通过
node index.js
开发,并将同一份代码部署到 AWS。

When to Use Web Functions

何时使用 Web Functions

  • Interactive HTTP traffic someone is waiting on: web app, HTTP API, or SSR site.
  • The app is already a port-listening HTTP server (Express, Fastify, Hono) and should stay one — no handler rewrite, no adapter library.
  • Handlers are I/O-bound (database, cache, another API, a model endpoint), so many requests share one execution environment and time spent waiting on I/O is not billed as CPU.
  • Response streaming matters: SSE, chunked transfer, or proxying LLM tokens as they are produced.
  • The endpoint should be reachable worldwide on one hostname without assembling CloudFront, API Gateway and Route53 by hand.
  • Traffic is spiky or unpredictable and should scale to zero.
  • 有人正在等待响应的交互式 HTTP 流量:Web 应用、HTTP API 或 SSR 网站。
  • 应用已经是一个监听端口的 HTTP 服务器(Express、Fastify、Hono),并且希望保持这种形态——无需重写 handler,也无需 adapter library。
  • Handler 属于 I/O 密集型(数据库、缓存、另一个 API 或模型端点),因此许多请求可以共享同一个执行环境,且等待 I/O 的时间不会按 CPU 计费。
  • 响应流式传输很重要:SSE、分块传输,或在生成 LLM token 时将其代理到客户端。
  • 端点应通过一个 hostname 在全球范围内访问,而无需手动组装 CloudFront、API Gateway 和 Route53。
  • 流量存在突发性或不可预测,需要自动缩容至零。

Hard preconditions

硬性前提条件

Any "no" rules Web Functions out. Invoke the
aws-serverless
skill to find a suitable service.
  • Runtime is Node.js —
    nodejs24.x
    . Python, Java, Go, .NET and Rust are not supported. Confirm the supported runtime list with
    aws lambda-web help
    or the AWS docs before routing a caller away.
  • Every native dependency has an arm64 (Graviton) build.
  • The work is an HTTP request/response (or stream) that a caller is waiting on. Queue, event-stream source (Kinesis, DynamoDB Streams), schedule, or event trigger are not supported.
  • One request completes within the 900 s (15 min) request timeout.
  • The app fits a 512 MB package and a 2 vCPU / 2 GB environment (see Service Limits).
  • Environments are stateless — any environment can serve any request. There is no affinity between an end user's session and a specific environment.
  • The app tolerates sharing an environment with concurrent requests. Strict per-request isolation is not supported.
只要有任意一项不满足,Web Functions 就不适用。调用
aws-serverless
skill 以寻找合适的服务。
  • Runtime 为 Node.js——
    nodejs24.x
    。不支持 Python、Java、Go、.NET 和 Rust。在将调用方转交给其他方案前,请通过
    aws lambda-web help
    或 AWS 文档确认受支持的 runtime 列表。
  • 每个原生依赖都有 arm64 (Graviton) 构建版本。
  • 工作负载是调用方正在等待完成的 HTTP request/response(或 stream)。不支持队列、事件流源(Kinesis、DynamoDB Streams)、定时任务或事件触发器。
  • 单个请求需在 900 s(15 min)请求超时内完成。
  • 应用需适配 512 MB 部署包和 2 vCPU / 2 GB 环境(参见服务限制)。
  • 环境是无状态的——任何环境都可以处理任何请求。终端用户会话与特定环境之间不存在亲和性。
  • 应用能够承受与并发请求共享同一环境。不支持严格的逐请求隔离。

Use Cases

使用场景

"What I'm building" → how it lands here.
The user is buildingShape on Web Functions
JSON HTTP API or REST backendExpress or Hono router, I/O-bound handlers, DynamoDB or RDS behind it → architecture-patterns.md
Server-side-rendered site or appRender HTML per request from
index.js
; no bundler needed unless you author JSX → architecture-patterns.md
LLM or AI gateway streaming tokens to a browserSSE or chunked responses; raise
timeoutSeconds
to cover the whole stream, not just the first byte → architecture-patterns.md
Webhook receiver (Stripe, GitHub, Slack)Verify the sender's signature against a signing secret from Secrets Manager before acting on the payload, then acknowledge fast and finish the work after responding — the environment stays running → architecture-patterns.md
Mobile or web backend-for-frontend aggregating several servicesOne environment fans several requests out concurrently, and time spent waiting is not billed as CPU
Single-page app plus its API from one deployment
express.static
for the bundle,
/*splat
fallback for client routes → static-assets.md
Internal service-to-service HTTP endpoint
authType: IamAuth
, so only SigV4-signed callers reach it → iam-and-security.md
Globally low-latency endpoint on a single hostname
MultiRegion
endpoint plus a region-agnostic app → domains-and-routing.md
App that calls RDS, ElastiCache or other private VPC resourcesAn egress network connector referenced from the revision; the endpoint stays public → networking.md
“用户正在构建什么” → “如何映射到 Web Functions”。
用户正在构建在 Web Functions 上的形态
JSON HTTP API 或 REST 后端Express 或 Hono router、I/O 密集型 handler,以及后端的 DynamoDB 或 RDS → architecture-patterns.md
服务端渲染的网站或应用在每次请求时通过
index.js
渲染 HTML;除非自行编写 JSX,否则无需 bundler → architecture-patterns.md
将 LLM 或 AI gateway 的 token 流式传输到浏览器使用 SSE 或分块响应;将
timeoutSeconds
调整为覆盖整个流,而不只是首字节 → architecture-patterns.md
Webhook 接收器(Stripe、GitHub、Slack)在处理 payload 前,使用 Secrets Manager 中的 signing secret 验证发送方签名,然后快速确认响应,并在响应后继续处理工作——环境会保持运行 → architecture-patterns.md
聚合多个服务的移动端或 Web backend-for-frontend一个环境并发发出多个请求,且等待时间不按 CPU 计费
通过一次部署同时提供单页应用及其 API使用
express.static
提供 bundle,并通过
/*splat
fallback 处理客户端路由 → static-assets.md
内部服务间 HTTP 端点使用
authType: IamAuth
,使只有经过 SigV4 签名的调用方能够访问 → iam-and-security.md
通过单一 hostname 提供全球低延迟端点使用
MultiRegion
endpoint 和与 Region 无关的应用 → domains-and-routing.md
调用 RDS、ElastiCache 或其他私有 VPC 资源的应用在 revision 中引用 egress network connector;端点仍保持公开 → networking.md

Workflow

工作流

Default to the
aws lambda-web
CLI — it's the quickest path. Use
aws lambda-web deploy
when the user asks for a single command or says they already deploy with it. It packages, uploads and creates or updates a project directory in one command, and
--hello-world
scaffolds and deploys a starter app (see Deploy (CLI) below). Otherwise, including for updates to an existing function, use the steps below. Use CloudFormation, CDK, SAM or Terraform when the user wants infrastructure-as-code or a repeatable production stack (see references/infrastructure-as-code.md).
  1. Scaffold - Express is inline below; for Hono or Fastify, read references/frameworks.md
  2. Choose endpoint auth — ask the user before deploying (see below); endpoints are public unless they pick
    IamAuth
  3. Test locally —
    node index.js
  4. Package — ZIP with production deps (up to 512 MB)
  5. Deploy —
    aws lambda-web create-web-function
  6. Verify — get endpoint URL, then curl
  7. Iterate — create a new revision
Public by default. A
ApplicationManaged
endpoint is reachable by anyone on the internet with the URL — there is no AWS-layer auth and no built-in WAF, and the URL is not a secret. Before deploying, ask the user which they want:
  • ApplicationManaged
    (public) — the app must implement its own authentication/authorization, input validation, and rate limiting.
  • IamAuth
    (internal) — only callers with valid IAM credentials (SigV4-signed) can reach it.
If the endpoint is public, the app owns its security. See references/iam-and-security.md for the security checklist (auth, input validation, rate limiting, WAF/CloudFront, least-privilege role, secrets).
默认使用
aws lambda-web
CLI——这是最快的方式。当用户要求使用单条命令,或表示自己已使用该命令部署时,使用
aws lambda-web deploy
。它通过一条命令完成打包、上传,并创建或更新项目目录;
--hello-world
则会生成并部署一个入门应用(见下文的“部署(CLI)”)。其他情况,包括更新现有 function,均使用以下步骤。当用户需要 infrastructure-as-code 或可复现的生产技术栈时,使用 CloudFormation、CDK、SAM 或 Terraform(参见 references/infrastructure-as-code.md)。
  1. 创建脚手架——Express 的代码内联如下;对于 Hono 或 Fastify,请阅读 references/frameworks.md
  2. 选择 endpoint auth——部署前询问用户(见下文);除非用户选择
    IamAuth
    ,否则 endpoint 均为公开
  3. 在本地测试——
    node index.js
  4. 打包——使用生产依赖生成 ZIP(最大 512 MB)
  5. 部署——
    aws lambda-web create-web-function
  6. 验证——获取 endpoint URL,然后执行 curl
  7. 迭代——创建新的 revision
默认公开。
ApplicationManaged
endpoint 可由互联网上任何知道该 URL 的人访问——AWS 层没有 auth,也没有内置 WAF,而且 URL 并非秘密。部署前,询问用户选择哪一种:
  • ApplicationManaged
    (公开)——应用必须自行实现身份验证和授权、输入验证以及速率限制。
  • IamAuth
    (内部)——只有持有有效 IAM 凭据(SigV4 签名)的调用方可以访问。
如果 endpoint 公开,安全由应用负责。参见 references/iam-and-security.md 中的安全检查清单(auth、输入验证、速率限制、WAF/CloudFront、最小权限 role、secrets)。

Quick Start (Express)

快速入门(Express)

javascript
// index.js
import express from 'express';
import helmet from 'helmet';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';

const __dirname = dirname(fileURLToPath(import.meta.url));
const app = express();
// The runtime probes this exact host:port for readiness.
const [HOST, PORT] = (process.env.AWS_LAMBDA_HTTP_ENDPOINT || '0.0.0.0:3000').split(':');

app.use(helmet());
app.use(express.static(join(__dirname, 'public')));
app.use(express.json({ limit: '10mb' }));
app.get('/api/health', (req, res) => res.json({ status: 'ok' }));
app.listen(PORT, HOST, () => console.log(`Listening on ${HOST}:${PORT}`));
json
{
  "name": "my-web-app",
  "type": "module",
  "scripts": { "start": "node index.js", "dev": "node --watch index.js" },
  "dependencies": { "express": "^5.0.0", "helmet": "^8.0.0" }
}
helmet
sets the security response headers (HSTS, CSP,
X-Content-Type-Options
,
X-Frame-Options
,
Referrer-Policy
) that no AWS layer sets for you here. On an
ApplicationManaged
endpoint the app is the only thing that can set them, so it belongs in the scaffold rather than being added later.
javascript
// index.js
import express from 'express';
import helmet from 'helmet';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';

const __dirname = dirname(fileURLToPath(import.meta.url));
const app = express();
// The runtime probes this exact host:port for readiness.
const [HOST, PORT] = (process.env.AWS_LAMBDA_HTTP_ENDPOINT || '0.0.0.0:3000').split(':');

app.use(helmet());
app.use(express.static(join(__dirname, 'public')));
app.use(express.json({ limit: '10mb' }));
app.get('/api/health', (req, res) => res.json({ status: 'ok' }));
app.listen(PORT, HOST, () => console.log(`Listening on ${HOST}:${PORT}`));
json
{
  "name": "my-web-app",
  "type": "module",
  "scripts": { "start": "node index.js", "dev": "node --watch index.js" },
  "dependencies": { "express": "^5.0.0", "helmet": "^8.0.0" }
}
helmet
用于设置安全响应头(HSTS、CSP、
X-Content-Type-Options
、
X-Frame-Options
、
Referrer-Policy
),而此处 AWS 层不会为你设置这些标头。在
ApplicationManaged
endpoint 上,应用是唯一能够设置这些标头的一方,因此应将其包含在初始代码中,而不是以后再补上。

Resource Naming

资源命名

All resources are project-scoped. Derive names from the function name:
ResourceDefault PatternExample
Function
{name}
my-api
IAM Role
{name}-web-role
my-api-web-role
S3 bucket
{name}-web-{account}
my-api-web-1234567890
S3 key
{name}/function.zip
my-api/function.zip
DynamoDB
{name}-{purpose}
my-api-items
Function names must be unique across all Regions in the account — the same name cannot exist in two Regions, and a collision fails at create time with a conflict error.
Ask the user which S3 strategy they prefer:
  • Separate bucket per project (default) — fully isolated, easy cleanup
  • Shared bucket across projects (e.g.,
    {account}-web-code
    ) — fewer resources, key-prefix isolation
  • Custom — user provides their own bucket name and key prefix
aws lambda-web deploy
names its own role (
awscli-lambdaweb-{name}
) and bucket (
awscli-lambdaweb-{account}-{region}-an
).
所有资源均按项目划分范围。请根据 function 名称派生资源名称:
资源默认模式示例
Function
{name}
my-api
IAM Role
{name}-web-role
my-api-web-role
S3 bucket
{name}-web-{account}
my-api-web-1234567890
S3 key
{name}/function.zip
my-api/function.zip
DynamoDB
{name}-{purpose}
my-api-items
Function 名称在同一账户的所有 Region 中必须唯一——同一名称不能存在于两个 Region 中,否则创建时会因冲突而失败。
询问用户偏好的 S3 策略:
  • 每个项目使用独立 bucket(默认)——完全隔离,便于清理
  • 多个项目共享 bucket(例如
    {account}-web-code
    )——资源更少,通过 key prefix 隔离
  • 自定义——由用户提供自己的 bucket 名称和 key prefix
aws lambda-web deploy
会自行命名 role(
awscli-lambdaweb-{name}
)和 bucket(
awscli-lambdaweb-{account}-{region}-an
)。

Deploy (CLI)

部署(CLI)

The
aws lambda-web
CLI is the primary, supported path — use it by default. The flow is: one-time S3 code bucket (versioning + Lambda read access), then
npm ci --omit=dev
→
zip
→
aws s3 cp
→
aws lambda-web create-web-function
with
--revision-config
and
--endpoint-config
, then wait for the endpoint to reach
Active
. If the project has a build step, run it before the prune —
npm ci --omit=dev
removes the bundler.
When the user asks for one command or already deploys with it,
aws lambda-web deploy --name {name} --code . --create --auth-type {auth-type}
(ask the user which auth type) zips, uploads, and creates the function, a code bucket, a role and a
dev
endpoint; rerun it without
--create
to ship changes. Install dependencies first.
For the full commands,
EndpointConfig
and
RevisionConfig
field rules, packaging, timeout, concurrency, environment variables, logging config and every
deploy
flag, see references/deployment.md. First-time setup (bucket, execution role, first deploy) is in references/getting-started.md. For CloudFormation, CDK or SAM, see references/infrastructure-as-code.md.
aws lambda-web
CLI 是主要且受支持的部署路径,应默认使用。流程如下: 先准备一次性的 S3 代码 bucket(版本控制 + Lambda 读取权限),然后执行
npm ci --omit=dev
→
zip
→
aws s3 cp
→ 使用
--revision-config
和
--endpoint-config
调用
aws lambda-web create-web-function
,随后等待 endpoint 变为
Active
。如果项目包含 build step,请在 prune 之前运行它——
npm ci --omit=dev
会移除 bundler。
当用户要求使用一条命令完成,或表示自己已使用该命令部署时,运行
aws lambda-web deploy --name {name} --code . --create --auth-type {auth-type}
(让用户选择 auth type),即可完成 zip、上传,并创建 function、代码 bucket、role 和
dev
endpoint;再次运行时不带
--create
即可发布变更。请先安装依赖。
有关完整命令、
EndpointConfig
和
RevisionConfig
字段规则、打包、超时、并发、环境变量、日志配置以及每个
deploy
flag,请参阅 references/deployment.md。首次设置(bucket、execution role、首次部署)请参阅 references/getting-started.md。 有关 CloudFormation、CDK 或 SAM,请参阅 references/infrastructure-as-code.md。

Multi-Region

多区域

Multi-region is supported: a
MultiRegion
endpoint serves your revision from several regions behind one hostname, with Route53 routing each caller to the nearest region.
PerRegion
additionally gives each region its own domain name. Both require
autoDeploymentMode: Disabled
, and the app must be region-agnostic — consecutive requests from one client can land in different regions, so keep state in a replicated store, never in the execution environment or
/tmp
.
See references/domains-and-routing.md for endpoint types, domains, traffic routing and the multi-region setup commands.
支持多区域部署:
MultiRegion
endpoint 会通过 一个 hostname 在多个 Region 中提供 revision,并由 Route53 将每个调用方路由到最近的 Region。
PerRegion
还会为每个 Region 分配各自的域名。两者都要求设置
autoDeploymentMode: Disabled
,并且应用必须与 Region 无关——同一客户端发出的连续请求可能落在不同 Region,因此应将状态保存在复制的存储中,绝不能保存在执行环境或
/tmp
中。
有关 endpoint 类型、域名、流量路由和多区域设置命令,请参阅 references/domains-and-routing.md。

VPC Egress

VPC Egress

By default a revision reaches the public internet over IPv4 and nothing private. To reach your VPC, put a version-qualified egress network connector ARN (
aws lambda-core create-network-connector
, compute type
WebFunction
) in the revision's
serviceConfig.egressNetworkConnectorArn
, serve it from a
HomeRegion
endpoint, and read the field back after every revision. See references/networking.md, or references/infrastructure-as-code.md to declare the connector and the revision in one stack.
默认情况下,revision 通过 IPv4 访问公共互联网,无法访问任何私有资源。要访问 VPC,请在 revision 的
serviceConfig.egressNetworkConnectorArn
中设置带版本限定符的 egress network connector ARN(
aws lambda-core create-network-connector
,compute type 为
WebFunction
),通过
HomeRegion
endpoint 提供服务,并在每次 revision 后回读该字段。参见 references/networking.md,或参阅 references/infrastructure-as-code.md,在同一个技术栈中声明 connector 和 revision。

Verify

验证

bash
aws lambda-web get-web-function-endpoint \
  --function-name {name} --endpoint-name default --region {region}
bash
aws lambda-web get-web-function-endpoint \
  --function-name {name} --endpoint-name default --region {region}

curl the domainName from the response

curl the domainName from the response

curl https://{domainName}/api/health

A revision that fails to start still goes `Active`, so curl a real route after every deploy. `aws lambda-web deploy` prints the endpoint as `endpointUrl` and names its first endpoint `dev`.

> Prefer waiters (`aws lambda-web wait ...`) over polling loops or `sleep`. Available: `web-function-active`, `web-function-revision-active`, `web-function-endpoint-active`, `web-function-endpoint-updated`, `web-function-endpoint-deleted`, `web-function-deleted`
curl https://{domainName}/api/health

启动失败的 revision 仍会变为 `Active`,因此每次部署后都应 curl 一个真实路由。`aws lambda-web deploy` 会将 endpoint 打印为 `endpointUrl`,并将其首个 endpoint 命名为 `dev`。

> 优先使用 waiters(`aws lambda-web wait ...`),而不是 polling loop 或 `sleep`。可用项包括:`web-function-active`、`web-function-revision-active`、`web-function-endpoint-active`、`web-function-endpoint-updated`、`web-function-endpoint-deleted`、`web-function-deleted`

Update Code

更新代码

bash
zip -r function.zip index.js package.json node_modules/ public/ \
  -x "*.test.*" -x ".git/*" -x ".env" -x "node_modules/.cache/*"
aws s3 cp function.zip s3://{bucket}/{name}/function.zip

aws lambda-web create-web-function-revision \
  --function-name {name} \
  --build-config '{
    "codeConfig": {"s3Object": {"bucket": "{bucket}", "key": "{name}/function.zip"}},
    "runtimeConfig": {"runtime": "nodejs24.x"}
  }' \
  --service-config '{"executionRoleArn": "arn:aws:iam::{account}:role/{name}-web-role"}' \
  --region {region}
bash
zip -r function.zip index.js package.json node_modules/ public/ \
  -x "*.test.*" -x ".git/*" -x ".env" -x "node_modules/.cache/*"
aws s3 cp function.zip s3://{bucket}/{name}/function.zip

aws lambda-web create-web-function-revision \
  --function-name {name} \
  --build-config '{
    "codeConfig": {
      "s3Object": {"bucket": "{bucket}", "key": "{name}/function.zip"}
    },
    "runtimeConfig": {"runtime": "nodejs24.x"}
  }' \
  --service-config '{"executionRoleArn": "arn:aws:iam::{account}:role/{name}-web-role"}' \
  --region {region}

Service Limits

服务限制

Subject to change — check the Lambda quotas page for the authoritative values.
ScopeResourceLimit
AccountRegional vCPU limit2,000
AccountRegional account rate limit100,000 RPS
AccountRegional per-endpoint maximum rate limit10,000 RPS
Per functionEndpoints10
Per functionRevisions retained50 (oldest unreferenced revisions are deleted automatically)
Per functionEnvironment variables32 KB total
Per functionDeployment package512 MB
Per functionFunction and endpoint name64 characters
Per endpointEndpoint rate limitLimited by Regional per-endpoint maximum rate limit (above). User can optionally configure a lower rate limit on individual endpoints via
throttleConfig.rateLimit
Per endpointActive revisions2
Per environmentvCPU2
Per environmentMemory2 GB
Per environmentConcurrency1–128 requests (see scaling-and-concurrency.md)
Per environmentNetwork bandwidth1 Gbps
Per environment
/tmp
512 MB
Per environmentFile descriptors1,024
Per environmentProcesses and threads1,024
Per environmentInit timeout10 seconds
Per requestTimeout3–900 s (default 30 s)
Per requestHeader count6,300
以下限制可能发生变化——请以 Lambda quotas page 中的权威数值为准。
范围资源限制
Account区域 vCPU 限额2,000
Account区域账户速率限制100,000 RPS
Account区域单 endpoint 最大速率限制10,000 RPS
每个 functionEndpoint 数量10
每个 function保留的 revision 数量50(最旧的未引用 revision 会自动删除)
每个 function环境变量总计 32 KB
每个 function部署包512 MB
每个 functionFunction 和 endpoint 名称64 个字符
每个 endpointEndpoint 速率限制受上方的区域单 endpoint 最大速率限制约束。用户也可以通过
throttleConfig.rateLimit
为单个 endpoint 配置更低的速率限制
每个 endpoint活跃 revision2
每个环境vCPU2
每个环境内存2 GB
每个环境并发数1–128 个请求(参见 scaling-and-concurrency.md)
每个环境网络带宽1 Gbps
每个环境
/tmp
512 MB
每个环境文件描述符1,024
每个环境进程和线程1,024
每个环境初始化超时10 秒
每个请求超时3–900 s(默认 30 s)
每个请求标头数量6,300

Cost Model

成本模型

Four billing dimensions: CPU, memory, requests, and data transfer. Check the Lambda pricing page for current rates — do not quote rates from memory. What decides an architecture is the shape of the bill:
  • Active CPU, not wall-clock duration. Time a request spends blocked on I/O — a database call, another API, a model endpoint — is not billed as CPU. Event Functions bill GB-seconds of wall-clock duration instead, so the same handler bills differently on each.
  • Memory is billed on consumption, not on a provisioned setting. An environment is 2 vCPU and 2 GB (see Service Limits) and there is no memory dial, so the familiar Event Functions move of raising memory to shorten duration has no equivalent here.
  • Concurrency is the density lever. One environment serves up to
    maxConcurrencyPerEnvironment
    requests, so an I/O-bound app keeps many requests in flight per environment instead of occupying one environment each.
Two consequences worth planning around:
  • I/O-bound workloads are the economical case. A handler that spends most of its life waiting on the network, sharing an environment with other requests, costs less here than the same handler billed per-invoke on wall-clock duration.
  • CPU-bound workloads give that advantage back. Heavy rendering, image processing or crypto burns billable CPU wherever it runs, and an environment is allocated 2 vCPU — of which a single-threaded Node process uses only one (see Anti-Patterns). For sustained high-volume CPU work, especially where committed-use discounts apply, compare
    aws-lambda-managed-instances
    .
An endpoint's scaling controls
scalingConfig.maxEnvironments
and
throttleConfig.rateLimit
can be used to limit potential cost. See scaling-and-concurrency.md for more details.
计费有四个维度:CPU、内存、请求和数据传输。请查看 Lambda pricing page 获取当前费率——不要凭记忆引用费率。决定架构的是账单形态:
  • 按活跃 CPU 计费,而非 wall-clock duration。 请求等待 I/O 的时间——例如数据库调用、另一个 API 或模型端点——不按 CPU 计费。Event Functions 则按 wall-clock duration 的 GB-seconds 计费,因此同一个 handler 在两种模式下的计费方式不同。
  • 按内存消耗量计费,而非预置设置。 环境为 2 vCPU 和 2 GB(参见服务限制),没有可调节的内存设置,因此 Event Functions 中通过提高内存来缩短耗时的常见做法在此没有对应方案。
  • 并发数是密度调节杠杆。 一个环境最多可处理
    maxConcurrencyPerEnvironment
    个请求,因此 I/O 密集型应用可以在每个环境中保持许多请求并行,而无需为每个请求独占一个环境。
有两个值得提前规划的结果:
  • I/O 密集型工作负载更具成本优势。 如果 handler 大部分时间都在等待网络,并与其他请求共享环境,那么其成本会低于按 wall-clock duration 对每次调用计费的同一 handler。
  • CPU 密集型工作负载会失去这一优势。 繁重的渲染、图像处理或加密无论在哪里运行都会消耗可计费 CPU,而每个环境分配了 2 vCPU——其中单线程 Node 进程只能使用一个(参见反模式)。对于持续的大规模 CPU 工作,尤其在可使用 committed-use discount 的情况下,应比较
    aws-lambda-managed-instances
    。
可通过 endpoint 的
scalingConfig.maxEnvironments
和
throttleConfig.rateLimit
控制扩展能力并限制潜在成本。更多细节请参阅 scaling-and-concurrency.md。

IAM Setup

IAM 设置

Trust policy principal:
lambda.amazonaws.com
IAM actions use the
lambda:
prefix. Resource ARN:
arn:aws:lambda:{region}:{account}:web-function/{name}
Action names match the API operations —
lambda:CreateWebFunction
,
lambda:CreateWebFunctionRevision
,
lambda:CreateWebFunctionEndpoint
,
lambda:UpdateWebFunctionEndpoint
, plus the
Get*
,
List*
, and
Delete*
variants. See references/iam-and-security.md for the full policy.
Resource ARN must include
/*
wildcard for endpoint/revision operations:
"Resource": ["arn:aws:lambda:{region}:{account}:web-function/{name}", "arn:aws:lambda:{region}:{account}:web-function/{name}/*"]
The caller also needs
s3:GetObject
+
s3:GetObjectVersion
on the code bucket (not just the execution role).
See references/iam-and-security.md for full policy examples.
信任策略 principal:
lambda.amazonaws.com
IAM 操作使用
lambda:
前缀。Resource ARN:
arn:aws:lambda:{region}:{account}:web-function/{name}
操作名称与 API 操作一致——
lambda:CreateWebFunction
、
lambda:CreateWebFunctionRevision
、
lambda:CreateWebFunctionEndpoint
、
lambda:UpdateWebFunctionEndpoint
,以及相应的
Get*
、
List*
和
Delete*
变体。完整策略请参阅 references/iam-and-security.md。
针对 endpoint/revision 操作,Resource ARN 必须包含
/*
通配符:
"Resource": ["arn:aws:lambda:{region}:{account}:web-function/{name}", "arn:aws:lambda:{region}:{account}:web-function/{name}/*"]
调用方还需要针对代码 bucket 的
s3:GetObject
和
s3:GetObjectVersion
权限,而不只是 execution role 需要这些权限。
完整策略示例请参阅 references/iam-and-security.md。

Anti-Patterns

反模式

What it looks like → why it fails → what to do instead.
Anti-patternWhy it failsInstead
Expecting a CPU-bound handler to use the whole environmentAn execution environment is allowed 2 vCPU, but Node is single-threaded, so one process uses one of them and the second sits idleFor CPU-bound work, use
worker_threads
(or
cluster
) to occupy both. Leave I/O-bound handlers single-threaded — they are not CPU-limited
Zipping a
node_modules
built on an x86 machine (laptop or x86 CI)
Execution environments are arm64, so an x86 native binary will not load. Packages such as
sharp
,
canvas
,
bcrypt
and other native addons ship per-architecture builds
Install and build on arm64 — an arm64 CI runner, a Graviton host, or a container run with
--platform linux/arm64
— then zip
Writing response bytes while the request body is still uploading (full-duplex streaming)The request path is half-duplex: the whole request body is forwarded before any response is read, so a large upload that expects an interleaved response stalls until the timeout. Small bodies fit socket buffers and appear to work, which hides it in testingRead the request to completion, then stream the response. Keep streaming in the server-to-client direction
Wrapping the app in a handler adapter (
serverless-express
,
@vendia/serverless-express
,
aws-lambda-fastify
)
There is no handler to export. The runtime loads
index.js
and expects a listening HTTP server; an adapter never binds a port, so readiness never passes and the environment is not usable
Delete the adapter and call
app.listen(...)
on the host and port from
AWS_LAMBDA_HTTP_ENDPOINT
Hardcoding
app.listen(3000)
, or binding
localhost
/
127.0.0.1
The runtime probes the exact address it advertises. A mismatched port or a loopback-only bind never answers that probeParse
AWS_LAMBDA_HTTP_ENDPOINT
and bind that host and port
Module-level mutable state holding per-request data — a
currentUser
, a request-scoped cache, a counter
One execution environment serves many concurrent requests in a single process, so requests read each other's values. This is a correctness and data-leak bug, not a performance oneKeep per-request data in the request scope; share only immutable config and SDK clients at module level
Writing session or upload state to
/tmp
and expecting it on the next request
/tmp
is per environment and shared between concurrent requests; the next request may land on a different environment, or a different Region on a multi-region endpoint
Keep state in DynamoDB, S3 or ElastiCache; use unique filenames for genuinely temporary files
Treating the endpoint URL as access control — "nobody knows this domain"An
ApplicationManaged
endpoint is reachable by anyone on the internet with the URL. No AWS-layer auth, no built-in WAF, and the URL is not a secret
Implement auth in the app, or use
IamAuth
; add CloudFront + WAF for L7 protection → iam-and-security.md
Secrets in
serviceConfig.environmentVariables
get-web-function-revision
returns environment variables in plaintext to anyone with read access to the revision
Keep the secret in Secrets Manager or SSM, pass only its name or path, fetch at runtime
Running
npm ci --omit=dev
before the build step
Pruning devDependencies deletes the bundler, so the build then fails with
esbuild: command not found
Build first, prune afterwards — or zip the bundled output → deployment.md
Expecting an
update-*
call to change code, runtime, timeout, env vars or concurrency in place
All of those live on the immutable revisionCreate a new revision. Only endpoint-level settings (auth, weights, scaling, throttle) update in place
Re-uploading to the same S3 key and expecting a redeployA revision is pinned to an object version; CloudFormation reports "No changes to deploy"Use a new key, or pass the new
versionId
Concluding the feature does not exist because
aws lambda-web
is missing
Absence means an outdated CLI, not a missing capabilityUpdate the AWS CLI → deployment.md
Reusing one function name in two RegionsFunction names are unique across all Regions in an account; the second create fails with a conflictSuffix the Region, or use one function with a
MultiRegion
endpoint
app.get('*', ...)
as an SPA fallback on Express 5
path-to-regexp v8 rejects a bare
*
and throws at startup, so the app never boots
Use
'/*splat'
→ static-assets.md
具体表现 → 失败原因 → 替代方案。
反模式失败原因替代方案
期望 CPU 密集型 handler 使用整个环境执行环境允许使用 2 vCPU,但 Node 是单线程的,因此一个进程只会使用其中一个,另一个会闲置对于 CPU 密集型工作,使用
worker_threads
(或
cluster
)占满两个 vCPU。让 I/O 密集型 handler 保持单线程——它们不受 CPU 限制
打包在 x86 机器(笔记本或 x86 CI)上构建的
node_modules
执行环境为 arm64,因此无法加载 x86 原生二进制文件。诸如
sharp
、
canvas
、
bcrypt
等包会按架构提供构建版本
在 arm64 上安装和构建——使用 arm64 CI runner、Graviton 主机,或通过
container
使用
--platform linux/arm64
运行——然后再打包
在请求体仍在上传时写入响应字节(全双工流式传输)请求路径是半双工的:完整请求体会先被转发,之后才会读取任何响应,因此大型上传若期望交错响应,会一直停滞直至超时。小型请求体能够装入 socket 缓冲区,看起来可以正常工作,从而在测试中掩盖问题先完整读取请求,再流式发送响应。保持从服务器到客户端方向上的流式传输
使用 handler adapter 包装应用(
serverless-express
、
@vendia/serverless-express
、
aws-lambda-fastify
)
没有可导出的 handler。运行时加载
index.js
并期待一个正在监听的 HTTP server;adapter 不会绑定端口,因此就绪检查永远无法通过,环境也不可用
删除 adapter,并根据
AWS_LAMBDA_HTTP_ENDPOINT
调用
app.listen(...)
绑定 host 和 port
硬编码
app.listen(3000)
,或绑定
localhost
/
127.0.0.1
运行时会对它声明的确切地址进行探测。端口不匹配或仅绑定 loopback 地址都永远无法响应探测解析
AWS_LAMBDA_HTTP_ENDPOINT
并绑定其中的 host 和 port
在模块级可变状态中保存逐请求数据——例如
currentUser
、请求级缓存或计数器
一个执行环境在单个进程中服务许多并发请求,因此请求会读取彼此的值。这不仅是性能问题,更是正确性和数据泄漏问题将逐请求数据保留在请求作用域内;模块级仅共享不可变配置和 SDK client
将 session 或 upload 状态写入
/tmp
,并期望在下次请求时仍然可用
/tmp
属于单个环境并由并发请求共享;下一个请求可能落到不同环境,或在多区域 endpoint 中落到不同 Region
将状态保存在 DynamoDB、S3 或 ElastiCache 中;真正临时文件使用唯一文件名
将 endpoint URL 当作访问控制——认为“没人知道这个域名”
ApplicationManaged
endpoint 可由互联网上任何知道该 URL 的人访问。AWS 层没有 auth,没有内置 WAF,而且 URL 并非秘密
在应用中实现 auth,或使用
IamAuth
;增加 CloudFront + WAF 以提供 L7 保护 → iam-and-security.md
在
serviceConfig.environmentVariables
中存放 Secrets
get-web-function-revision
会以明文向任何拥有 revision 读取权限的人返回环境变量
将 secret 保存在 Secrets Manager 或 SSM 中,只传递其名称或路径,并在运行时获取
在 build step 之前运行
npm ci --omit=dev
裁剪 devDependencies 会删除 bundler,导致 build 失败并出现
esbuild: command not found
先执行 build,再执行 prune——或者直接打包 bundle 后的输出 → deployment.md
期望通过
update-*
调用原地修改 code、runtime、timeout、env vars 或 concurrency
所有这些配置都位于不可变的 revision 中创建新的 revision。只有 endpoint 级设置(auth、weights、scaling、throttle)可以原地更新
重新上传到同一个 S3 key 后期望重新部署Revision 固定到特定的 object version;CloudFormation 会报告
No changes to deploy
使用新的 key,或传入新的
versionId
因为缺少
aws lambda-web
就断定该功能不存在
缺少命令意味着 CLI 版本过旧,而不是缺少该能力更新 AWS CLI → deployment.md
在两个 Region 中复用同一个 function 名称Function 名称在同一账户的所有 Region 中必须唯一;第二次创建会因冲突而失败添加 Region 后缀,或者使用一个 function 配合
MultiRegion
endpoint
在 Express 5 中使用
app.get('*', ...)
作为 SPA fallback
path-to-regexp v8 不接受裸
*
,并在启动时抛出异常,导致应用无法启动
使用
'/*splat'
→ static-assets.md

Troubleshooting — Start Here

故障排查——从这里开始

The five that account for most failed first deploys. Full symptom → cause → fix tables are in troubleshooting.md.
SymptomCauseFixVerify
Endpoint never reaches
Active
; state goes
Failed
The app never bound the advertised host and port, so readiness never passedBind the host and port from
AWS_LAMBDA_HTTP_ENDPOINT
get-web-function-endpoint
reports
Active
, then curl
domainName
500 with
Cannot find module '/var/task/index.js'
Entry point is not
index.js
—
.mjs
,
server.js
, or nested in
dist/
Deploy with
aws lambda-web deploy --entry-point {file}
, or rename the entry point to
index.js
at the ZIP root
unzip -l function.zip
lists
index.js
at the top level
Stuck in
Pending
past 10 minutes
Execution-role trust policy principal is not
lambda.amazonaws.com
Fix the trust policy, then create a new revision
aws iam get-role
shows the correct principal
create-web-function-revision
returns 500 with no message
The caller lacks
s3:GetObject
/
s3:GetObjectVersion
on the code bucket — not the execution role
Add both to the caller's policyThe revision reaches
Active
invalid choice: 'lambda-web'
, or
Unknown parameter "BuildConfig"
Outdated AWS CLI; or PascalCase JSON keysUpdate the CLI; use camelCase (
buildConfig
,
codeConfig
)
aws lambda-web help
lists the web-function commands
以下五项占首次部署失败的大多数。完整的“症状 → 原因 → 修复”对照表位于 troubleshooting.md。
症状原因修复验证
Endpoint 始终未达到
Active
,状态变为
Failed
应用从未绑定所声明的 host 和 port,因此就绪检查始终无法通过根据
AWS_LAMBDA_HTTP_ENDPOINT
绑定 host 和 port
get-web-function-endpoint
报告
Active
,然后 curl
domainName
返回 500,并显示
Cannot find module '/var/task/index.js'
入口点不是
index.js
——可能是
.mjs
、
server.js
,或位于
dist/
嵌套目录中
使用
aws lambda-web deploy --entry-point {file}
部署,或者将入口文件重命名为 ZIP 根目录下的
index.js
unzip -l function.zip
显示
index.js
位于顶层
超过 10 分钟后仍停留在
Pending
Execution-role 信任策略的 principal 不是
lambda.amazonaws.com
修复信任策略,然后创建新的 revision
aws iam get-role
显示正确的 principal
create-web-function-revision
返回 500,但没有消息
调用方缺少针对代码 bucket 的
s3:GetObject
/
s3:GetObjectVersion
权限——问题不在 execution role
在调用方策略中添加这两个权限Revision 达到
Active
invalid choice: 'lambda-web'
,或
Unknown parameter "BuildConfig"
AWS CLI 版本过旧;或者 JSON 键使用了 PascalCase更新 CLI;使用 camelCase(
buildConfig
、
codeConfig
)
aws lambda-web help
列出 web-function 命令

Migration

迁移

Moving an existing Node.js HTTP app here is mostly a delete-code exercise — the adapter, the handler export and the API Gateway wiring all go away, and the router itself does not change.
Four source shapes each have a step-by-step path, a preflight checklist, the features with no equivalent, and a traffic-cutover procedure: an adapter-wrapped app, API Gateway + Lambda proxy, a Lambda function URL, and a container on Fargate, App Runner or EC2. See migration.md.
将现有 Node.js HTTP 应用迁移到这里,主要就是删除代码——adapter、handler export 和 API Gateway wiring 都会消失,而 router 本身无需改动。
对于四种 source shape,每一种都有分步迁移路径、preflight checklist、没有对应能力的功能以及流量切换流程:使用 adapter 包装的应用、API Gateway + Lambda proxy、Lambda function URL,以及运行在 Fargate、App Runner 或 EC2 上的 container。 请参阅 migration.md。

When to Load Reference Files

何时加载参考文件

Match on meaning, not exact wording — any trigger word in a row should pull that file.
Read thisTrigger words
getting-started.mdfirst deploy, get started, set up, prerequisites, hello world,
--hello-world
, starter app, new project, from scratch, S3 code bucket, execution role, bootstrap, my first web function
frameworks.mdExpress, Fastify, Hono, TypeScript,
.ts
, type stripping, ESM,
type: module
, scaffold, project structure, entry point,
index.js
, router, middleware
deployment.mddeploy, redeploy, ship, release, CLI,
aws lambda-web
,
aws lambda-web deploy
, one command, revision, endpoint, packaging, ZIP,
npm ci
, timeout, environment variables, env vars, canary, blue/green, traffic weights, rollback,
versionId
scaling-and-concurrency.mdscaling controls, concurrency,
maxConcurrencyPerEnvironment
,
scalingConfig
,
maxEnvironments
,
throttleConfig
,
rateLimit
, throttling, RPS limit, vCPU quota
infrastructure-as-code.mdCloudFormation, CFN, CDK,
CfnResource
, escape hatch, SAM, Terraform, HashiCorp, HCL, infrastructure as code, IaC, template, stack,
AWS::Lambda::WebFunction
,
AWS::Lambda::NetworkConnector
, VPC egress in a stack, repeatable deployment, pipeline
static-assets.mdstatic files, static assets, CSS, JS bundle, images, favicon,
public/
,
express.static
, SPA, single-page app, client-side routing, fallback route, bundling, esbuild, Vite, cache headers
domains-and-routing.mdmulti-region, multiregion, global, latency routing, Route53, domain, custom domain, hostname, HTTPS, TLS, endpoint type,
HomeRegion
,
MultiRegion
,
PerRegion
, CORS, auth type,
ApplicationManaged
,
IamAuth
iam-and-security.mdIAM, policy, permissions, role, trust policy,
PassRole
, least privilege, AccessDenied, security, auth, authentication, authorization, public endpoint, WAF, DDoS, rate limiting, secrets, KMS, encryption, security headers,
helmet
observability.mdlogs, logging, log group, log level, CloudWatch, metrics, monitoring, alarms, tracing, CloudTrail, audit, structured logging, health check, which region served, debug in production
architecture-patterns.mdSSR, server-side rendering, React, JSX, streaming, SSE, server-sent events, LLM, AI gateway, token streaming, long-lived connection, webhook, background task, fire and forget, API backend, DynamoDB, connection pooling, thread safety, concurrency model
troubleshooting.mderror, fails, failing, broken, not working, 500, 502, 403, 404,
ECONNREFUSED
,
ERR_MODULE_NOT_FOUND
, module not found, stuck,
Pending
,
Failed
, never becomes active, AccessDenied, ParamValidation, no logs, debug, why doesn't
networking.mdVPC, private subnet, RDS, Aurora, ElastiCache, private resources, VPC endpoint, PrivateLink, network connector, egress,
egressNetworkConnectorArn
,
lambda-core
, NAT gateway, security group, private DNS, private hosted zone, IPv6, DualStack, static outbound IP
migration.mdmigrate, migration, move, port, switch, convert, coming from, replace,
serverless-express
, adapter, wrapper, handler export, function URL, API Gateway proxy, Fargate, App Runner, containerized, lift and shift
请按含义匹配,而不是按确切措辞——一行中的任一 trigger word 都应加载对应文件。
读取此文件Trigger words
getting-started.mdfirst deploy, get started, set up, prerequisites, hello world,
--hello-world
, starter app, new project, from scratch, S3 code bucket, execution role, bootstrap, my first web function
frameworks.mdExpress, Fastify, Hono, TypeScript,
.ts
, type stripping, ESM,
type: module
, scaffold, project structure, entry point,
index.js
, router, middleware
deployment.mddeploy, redeploy, ship, release, CLI,
aws lambda-web
,
aws lambda-web deploy
, one command, revision, endpoint, packaging, ZIP,
npm ci
, timeout, environment variables, env vars, canary, blue/green, traffic weights, rollback,
versionId
scaling-and-concurrency.mdscaling controls, concurrency,
maxConcurrencyPerEnvironment
,
scalingConfig
,
maxEnvironments
,
throttleConfig
,
rateLimit
, throttling, RPS limit, vCPU quota
infrastructure-as-code.mdCloudFormation, CFN, CDK,
CfnResource
, escape hatch, SAM, Terraform, HashiCorp, HCL, infrastructure as code, IaC, template, stack,
AWS::Lambda::WebFunction
,
AWS::Lambda::NetworkConnector
, VPC egress in a stack, repeatable deployment, pipeline
static-assets.mdstatic files, static assets, CSS, JS bundle, images, favicon,
public/
,
express.static
, SPA, single-page app, client-side routing, fallback route, bundling, esbuild, Vite, cache headers
domains-and-routing.mdmulti-region, multiregion, global, latency routing, Route53, domain, custom domain, hostname, HTTPS, TLS, endpoint type,
HomeRegion
,
MultiRegion
,
PerRegion
, CORS, auth type,
ApplicationManaged
,
IamAuth
iam-and-security.mdIAM, policy, permissions, role, trust policy,
PassRole
, least privilege, AccessDenied, security, auth, authentication, authorization, public endpoint, WAF, DDoS, rate limiting, secrets, KMS, encryption, security headers,
helmet
observability.mdlogs, logging, log group, log level, CloudWatch, metrics, monitoring, alarms, tracing, CloudTrail, audit, structured logging, health check, which region served, debug in production
architecture-patterns.mdSSR, server-side rendering, React, JSX, streaming, SSE, server-sent events, LLM, AI gateway, token streaming, long-lived connection, webhook, background task, fire and forget, API backend, DynamoDB, connection pooling, thread safety, concurrency model
troubleshooting.mderror, fails, failing, broken, not working, 500, 502, 403, 404,
ECONNREFUSED
,
ERR_MODULE_NOT_FOUND
, module not found, stuck,
Pending
,
Failed
, never becomes active, AccessDenied, ParamValidation, no logs, debug, why doesn't
networking.mdVPC, private subnet, RDS, Aurora, ElastiCache, private resources, VPC endpoint, PrivateLink, network connector, egress,
egressNetworkConnectorArn
,
lambda-core
, NAT gateway, security group, private DNS, private hosted zone, IPv6, DualStack, static outbound IP
migration.mdmigrate, migration, move, port, switch, convert, coming from, replace,
serverless-express
, adapter, wrapper, handler export, function URL, API Gateway proxy, Fargate, App Runner, containerized, lift and shift

Guardrail — where this skill's own files live (MCP vs local install)

护栏——此 skill 自身的文件存放在哪里(MCP 与本地安装)

This skill can be loaded two ways, and they resolve the skill's own bundled files — the
references/
documents — from different places. Determine how the skill was loaded before you read a reference:
  • Loaded through the AWS MCP
    retrieve_skill
    tool call.
    The skill is not installed on the local filesystem; its reference files do not exist on disk. You MUST fetch each reference through the same
    retrieve_skill
    tool by passing the
    file
    parameter (for example,
    file="references/deployment.md"
    ). Do NOT
    file_read
    these paths from the local or working directory, and do NOT search the filesystem for them — they are not there, and any local file that happens to match the name is unrelated to this skill.
  • Installed locally (the skill lives in a local skills directory such as
    .claude/skills/aws-lambda-web-functions/
    ,
    ~/.claude/skills/aws-lambda-web-functions/
    , or
    .kiro/skills/aws-lambda-web-functions/
    ). Read references from the local skill directory using the relative paths shown throughout this document.
This distinction applies only to the skill's own packaged files. The user's application code —
index.js
,
package.json
,
public/
, the
function.zip
you build — is always read from and written to the user's working directory regardless of how the skill was loaded. Never fetch or write customer data through
retrieve_skill
.
此 skill 可以通过两种方式加载,它们会从不同位置解析该 skill 自带的文件——即
references/
文档。读取 reference 前,请先确定 skill 的加载方式:
  • 通过 AWS MCP
    retrieve_skill
    工具调用加载。
    Skill 并未安装在本地文件系统上;其 reference 文件在磁盘上不存在。必须通过同一个
    retrieve_skill
    工具获取每个 reference,并传入
    file
    参数(例如
    file="references/deployment.md"
    )。不要通过
    file_read
    读取这些路径,也不要在本地文件系统中搜索它们——这些文件并不存在,任何恰好同名的本地文件都与此 skill 无关。
  • 在本地安装(skill 位于本地 skills 目录,例如
    .claude/skills/aws-lambda-web-functions/
    、
    ~/.claude/skills/aws-lambda-web-functions/
    或
    .kiro/skills/aws-lambda-web-functions/
    )。使用本文档各处所示的相对路径,从本地 skill 目录读取 reference。
此区别仅适用于该 skill 自身打包的文件。用户的应用代码——
index.js
、
package.json
、
public/
以及你构建的
function.zip
——无论 skill 如何加载,始终从用户的工作目录读取并写入。切勿通过
retrieve_skill
获取或写入客户数据。

Critical Rules

关键规则

  1. Node 24 only —
    nodejs24.x
    is the only runtime; runtime support can change, so confirm with
    aws lambda-web help
    or the AWS docs before assuming a newer version is unavailable
  2. Entry point is
    index.js
    — the runtime loads
    /var/task/index.js
    , not
    .mjs
    . When your entry file has another name (
    server.js
    ,
    app.mjs
    ),
    aws lambda-web deploy
    detects it or takes
    --entry-point
    and ships a small
    index.js
    that imports it; a ZIP you build yourself needs
    index.js
    at its root
  3. Bind the host and port from
    AWS_LAMBDA_HTTP_ENDPOINT
    — the runtime probes that exact address, so a hardcoded port that does not match it, or a loopback-only bind, fails readiness and the environment is not usable. There is no
    PORT
    env var
  4. "type": "module"
    in package.json
    — required for ESM imports from
    index.js
  5. No handler exports — your app is an HTTP server
  6. Write thread-safe code — one execution environment serves many concurrent requests; avoid global mutable state
  7. Code, runtime, timeout, env vars and concurrency all live on the revision — changing any of them requires a new revision, not an in-place update
  8. Background tasks work natively — the environment stays running after response
  9. Streaming native — chunked transfer-encoding, SSE out of the box
  10. TypeScript works natively — Node 24 type stripping, use
    index.js
    shim +
    import type
  11. Code comes only from a ZIP in S3 —
    deploy
    builds and uploads it for you; otherwise supply it through
    codeConfig.s3Object
    and bundle shared code into the package. For container images and a layers equivalent, confirm against
    aws lambda-web create-web-function-revision help
    or the API reference rather than assuming either is available
  1. 仅支持 Node 24——
    nodejs24.x
    是唯一 runtime;runtime 支持情况可能变化,因此不要在假定更新版本不可用之前,先通过
    aws lambda-web help
    或 AWS 文档进行确认
  2. 入口点是
    index.js
    ——runtime 加载
    /var/task/index.js
    ,而不是
    .mjs
    。当入口文件使用其他名称(
    server.js
    、
    app.mjs
    )时,
    aws lambda-web deploy
    会检测到它或采用
    --entry-point
    ,并随包发送一个导入它的小型
    index.js
    ;自行构建 ZIP 时,根目录中必须有
    index.js
  3. 从
    AWS_LAMBDA_HTTP_ENDPOINT
    绑定 host 和 port
    ——runtime 会对该确切地址进行探测,因此硬编码不匹配的端口或仅绑定 loopback 地址都会导致就绪检查失败,环境也不可用。不存在
    PORT
    环境变量
  4. package.json 中需要
    "type": "module"
    ——
    index.js
    使用 ESM imports 时必需
  5. 不导出 handler——应用是 HTTP server
  6. 编写 thread-safe code——一个执行环境会服务许多并发请求;避免使用全局可变状态
  7. Code、runtime、timeout、env vars 和 concurrency 全部位于 revision 中——修改其中任何一项都需要创建新的 revision,而不是原地更新
  8. 原生支持后台任务——响应完成后环境会继续运行
  9. 原生支持流式传输——原生支持 chunked transfer-encoding 和 SSE
  10. 原生支持 TypeScript——使用 Node 24 type stripping,并使用
    index.js
    shim +
    import type
  11. 代码只能来自 S3 中的 ZIP——
    deploy
    会为你构建并上传代码;否则应通过
    codeConfig.s3Object
    提供代码,并将共享代码打包进 package。对于 container image 以及 layers 的等效能力,请对照
    aws lambda-web create-web-function-revision help
    或 API reference 进行确认,不要假定二者可用