AWS SAM 无服务器应用实战教程(2026 最新):从本地调试到一键部署,附免费额度与成本测算

📅 · ChengziCloud - 一站式云端服务

Meta Description: AWS SAM 实战教程:用 SAM CLI 从零搭建 Lambda + API Gateway 无服务器应用,含 sam init/build/local/deploy 全流程命令、template.yaml 逐段讲解、2026 官方真实单价与免费额度表、成本测算与 8 大避坑点。

> 关键词:AWS SAM、Serverless Application Model、SAM CLI、Lambda 部署、无服务器实战、sam deploy、AWS 免费套餐

一、前言:会写 Lambda 和能上线 Lambda 是两回事

很多人第一次用 AWS Lambda 的路径是这样的:在控制台点开函数、粘一段代码、点 Deploy、再去 API Gateway 手工建一个触发器,最后手动复制 ARN 和环境变量。跑通一个演示没问题,但只要涉及两个以上函数、一张表、几个环境变量,再加上"测试环境与生产环境各一套",控制台点法就会立刻失控——你记不清生产环境的超时是 30 秒还是 3 秒,也说不清上周那个 IAM 权限是谁手工加的。

AWS SAM(Serverless Application Model)解决的正是这件事:它把"函数 + API + 表 + 权限 + 环境变量"整体当作一个可以版本化、可以 diff、可以一键重建的应用来管理。

一句话决策口诀:CloudFormation 管通用资源,SAM 管无服务器资源,Lambda 控制台只用来临时看一眼。

动手之前,先把本站几篇相邻文章的分工划清,避免重复阅读:

| 既有主题 | 它解决的问题 | 与本文的关系 | |---|---|---| | Lambda 无服务器 API 实战 | 函数本身怎么写、触发器怎么配、冷启动怎么优化 | 本文的运行时底座,不重复函数代码细节 | | CloudFormation 基础设施即代码实战 | 通用资源的 IaC 语法与 Stack 生命周期 | 本文的底层引擎,SAM 最终会编译成它 | | API Gateway 深度实战 | HTTP / REST / WebSocket 的类型选择与鉴权 | 本文只讲如何用 SAM 声明式地把 API 建出来 | | Step Functions 工作流编排 | 多步骤长流程的编排 | 本文的下游能力,SAM 可直接声明状态机 |

本文只讲一件事:一个无服务器应用怎么写出来、怎么在本机调试、怎么一键部署到 AWS,以及这套东西一个月到底花多少钱。

二、AWS SAM 到底是什么:三层理解

第一层,它是一个开源框架。 AWS 官方原文的表述是:AWS Serverless Application Model (AWS SAM) is an open-source framework for building serverless applications using infrastructure as code (IaC)。注意两个关键词——open-source(它不是一个封闭的厂商工具,Microsoft 等厂商也在参与贡献)、IaC(基础设施即代码)。

第二层,它是一种"简写语法"。 官方说法是:developers declare CloudFormation resources and specialized serverless resources that are transformed to infrastructure during deployment。也就是说,SAM 模板本质上是 CloudFormation 模板的超集——你平时写的 AWS::Lambda::Function、AWS::IAM::Role、AWS::ApiGatewayV2::Api 这些原生资源都能直接放进 SAM 模板;而 SAM 额外提供了几个"专用资源类型",用十几行就能描述原本要上百行的东西。

常用的 SAM 专用资源类型有:

- AWS::Serverless::Function:函数 + 执行角色 + 事件源(API、定时、队列……)三合一 - AWS::Serverless::Api / AWS::Serverless::HttpApi / AWS::Serverless::WebSocketApi:三种 API 网关形态 - AWS::Serverless::SimpleTable:一张 DynamoDB 表(只需主键即可用) - AWS::Serverless::StateMachine:Step Functions 状态机 - AWS::Serverless::LayerVersion:Lambda 层 - AWS::Serverless::Connector:自动推导两个资源之间所需的 IAM 权限 - AWS::Serverless::Application:引用现成的公共应用模板

第三层,它是一套开发工作流。 SAM CLI 覆盖了 authoring → build → deploy → test → monitor 全生命周期:sam init 起项目、sam build 构建依赖、sam validate 校验模板、sam local invoke 与 sam local start-api 在本地跑、sam deploy 部署、sam sync 边改边同步到云端。

这里有一条必须先说清的结论:SAM 本身不额外收费。 你只为它创建出来的 Lambda、API Gateway、DynamoDB 等资源付费;SAM CLI 是跑在你自己机器上的本地工具,模板展开(transform)由 CloudFormation 在部署时完成,而 CloudFormation 本身也不按资源数量收费。所以"用 SAM 会不会多花一笔钱"这个担心可以完全放下——下文第八节会把真正花钱的那几项单价列成表。

三、上手前的准备:装 SAM CLI 与三个依赖

写教程最忌讳把版本号写死——上游一发新版,文中的下载链接就 404,文章从"有用"变成"有害"。SAM CLI 的最新版本应当在运行时解析,而不是抄一个快照。本文写作时(2026 年 9 月)查到的版本是 v1.166.2,发布于 2026-09-11,你可以用下面这条命令随时自查当前最新版:

`bash curl -s https://api.github.com/repos/aws/aws-sam-cli/releases/latest \ | grep -o '"tag_name": "[^"]"' `

安装方式按平台选一种:

`bash // macOS / Linux:Homebrew brew install aws-sam-cli

// 任意平台:pip pip install --user aws-sam-cli

// 校验 sam --version `

除了 SAM CLI,还需要三样东西:

| 依赖 | 用途 | 校验命令 | |---|---|---| | AWS CLI v2 | 提供凭证与底层调用能力 | aws sts get-caller-identity | | SAM CLI | 构建、本地调试、部署 | sam --version | | Docker(或 Finch) | sam local 系列与容器镜像构建需要 | docker info | | Git | sam init 拉取模板 | git --version |

Docker 不是可选项,这点必须强调。 sam local invoke、sam local start-api 的完整功能,以及 sam build --use-container 的容器构建模式,都依赖 Docker 在本地模拟 Lambda 运行时。如果你的机器上没有 Docker,sam local 会直接报错。若只是想先跑通一个 Hello World,可以退而用不指定 --use-container 的本地构建模式,但前提是本机已经装好了对应语言的运行时(如 Python 3.13)。

凭证配置是另一个高频卡点。本地调试用的是你本机 AWS CLI 的凭证:

`bash aws configure aws sts get-caller-identity `

第二条命令会打印出当前身份(账号 ID、用户/角色 ARN)。如果它报错,先别急着往下走——后面所有 sam deploy 都会失败。建议给 SAM 项目单独建一个 IAM 用户或角色,而不是直接用账号根的访问密钥。

四、sam init:三分钟起一个规范项目

`bash sam init `

交互式会问四个问题:项目名、模板来源(AWS Quick Start 或自定义)、运行时(python3.13 / nodejs22.x / java21 / go1.x / dotnet8 / ruby3.4 等)、依赖管理方式。想跳过交互直接生成:

`bash sam init \ --runtime python3.13 \ --architecture arm64 \ --app-template hello-world \ --name my-serverless-app `

--architecture arm64 这一项值得单独说一句:Graviton(Arm)架构下 Lambda 的每 GB-秒单价明显更低(第八节的价格表会给出具体倍数),同样的代码通常能省下约两成执行费用,只有用到 x86 专用二进制依赖时才需要回到 x86_64。

生成出来的项目结构大致如下(以 Python Hello World 为例):

`text my-serverless-app/ ├── template.yaml # 应用的全部基础设施定义 ├── samconfig.toml # 部署参数(区域、栈名、S3 产物桶等) ├── README.md ├── events/ │ └── event.json # 本地调试用的模拟事件 └── hello_world/ ├── app.py # 函数代码 └── requirements.txt # 依赖 `

这里有个第一次用 SAM 的人几乎都会困惑的点:template.yaml 和函数代码是同一个交付单元。 你不需要先在控制台建函数、再单独上传代码——模板里已经声明了代码路径,sam build 会把代码和依赖一起打进构建产物,sam deploy 一起上传。这正是 SAM 与"控制台点点点"最本质的差别:应用的定义与实现被绑定成了一个可版本化的对象。

五、读懂模板:一个完整可用的 template.yaml

SAM 的全部威力都在这一份 YAML 里。下面是一个去掉了所有冗余、可以直接部署的"Hello World + HTTP API"模板:

`yaml AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31

Globals: Function: Timeout: 10 MemorySize: 512 Runtime: python3.13 Architectures: - arm64

Parameters: Stage: Type: String Default: dev

Resources: HelloFunction: Type: AWS::Serverless::Function Properties: Handler: app.lambda_handler CodeUri: hello_world/ Environment: Variables: STAGE: !Ref Stage Events: HelloApi: Type: HttpApi Properties: Path: /hello Method: get

Outputs: HelloApiUrl: Description: API endpoint URL Value: !Sub https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com `

逐段拆开看,一共只有五个部分:

1)Transform: AWS::Serverless-2016-10-31 —— 整个 SAM 的开关。 这一行告诉 CloudFormation:本模板里含有 SAM 专用资源,请先做宏展开,把 AWS::Serverless::* 编译成标准 CloudFormation 资源再执行。漏掉这一行,部署时会直接报"无法识别的资源类型",这是新手第一个坑。 注意 AWSTemplateFormatVersion 和 Transform 是两个不同的字段,前者是模板格式版本,后者才是 SAM 的开关。

2)Globals —— 全局默认值。 写在 Globals.Function 下的配置会被模板里所有函数继承。一个项目里如果有五个函数,共用同一套超时和内存,就不用写五遍。个别函数需要不同配置时,写在它自己的 Properties 里覆盖即可——SAM 的覆盖优先级是"函数级 > Globals"。

3)Parameters —— 部署时传入的变量。 配合 sam deploy --parameter-overrides Stage=prod,同一份模板就能同时服务测试与生产。这是"一套模板多环境"最轻量的实现方式,比复制两份模板去维护要可靠得多。

4)Resources —— 核心部分。 一个 AWS::Serverless::Function 资源,实际上同时生成了:Lambda 函数本体、一个执行角色(含基础日志权限)、以及因为 Events 里声明了 HttpApi 而自动创建的 API Gateway、路由、集成与调用权限。这就是 SAM 的简写价值:同样的功能若用原生 CloudFormation 手写,通常要 80~120 行(Function + Role + Api + Stage + Integration + Route + Lambda Permission 等一连串资源),而 SAM 只要三十来行,且不容易漏配。

5)Outputs —— 部署完成后打印出来的信息。 上面例子里输出的是 API 的访问地址。实践中最有用的一条经验是:把所有需要人工知道的值(API URL、S3 桶名、表名、队列 URL)都写成 Output,这样 sam deploy 结束时会直接列在终端里,不用再回控制台一个个找。

关于 Events,值得单独展开一下,因为它是 SAM 相对原生 CloudFormation 帮助最大的一段。只需改几行 YAML,就能把同一份函数代码接到不同事件源上:

| 事件源类型 | 写法 | 等价于手工配置 | |---|---|---| | HTTP API(推荐) | Type: HttpApi | API Gateway HTTP API + 路由 + 权限 | | REST API | Type: Api | API Gateway REST API + 部署 + 阶段 | | 定时触发 | Type: Schedule + Schedule: rate(5 minutes) | EventBridge 规则 + 权限 | | 队列触发 | Type: SQS + Queue: !GetAtt MyQueue.Arn | 事件源映射 + 批量参数 | | 对象存储触发 | Type: S3 + Bucket: !Ref MyBucket | 桶通知配置 + 权限 |

这张表是整篇文章里最值得记住的东西:在控制台里配这五种触发器是五套完全不同的界面,而在 SAM 里它们是同一个 Events 字段下的五个键。这也解释了为什么 SAM 特别适合"函数代码几乎不变、触发器总要调整"的迭代期项目。

六、本地调试:不产生一分钱 AWS 费用的联调方式

SAM CLI 最值钱的功能其实是本地调试——不用部署到云端就能验证逻辑,这对还在免费额度期内的账号尤其重要(本地跑多少次都不计费)。

构建与单次调用:

`bash sam build sam local invoke HelloFunction --event events/event.json `

sam local invoke 会在本地用 Docker 起一个与线上一致的 Lambda 运行时,把 events/event.json 当作入参喂给函数,返回值直接打印在终端。想看 HTTP 层的行为,就把 API 也起在本地:

`bash sam local start-api --port 3000 curl http://127.0.0.1:3000/hello `

不用自己猜各种事件源的 JSON 结构——SAM CLI 能直接生成官方样例事件:

`bash sam local generate-event apigateway http-api-proxy sam local generate-event s3 put sam local generate-event sqs receive-message sam local generate-event schedule `

需要断点调试、或者想模拟环境变量时:

`bash sam local start-api --env-vars env.json --debug-port 5858 `

env.json 里按函数名分组写变量。这里有个很典型的坑:很多人只在本地 env.json 里配了环境变量,却忘了把它们写进 template.yaml 的 Environment.Variables,结果本地一切正常、部署到线上函数读不到变量。判断标准很简单——凡是函数运行需要的变量,必须以模板里的声明为准,env.json 只是本地覆盖用的便利层。

另外提醒一点:sam local 用 Docker 模拟运行时,首次拉取镜像会花几分钟,之后才有"秒级启动"的体验。如果公司网络访问 Docker Hub 较慢,可以先手动 docker pull 好对应镜像,或者配置镜像加速。

七、部署:sam deploy 与 sam sync

首次部署建议用引导模式:

`bash sam deploy --guided `

它会依次询问:栈名、目标区域、是否确认变更集、是否允许创建 IAM 角色、用于存放构建产物的 S3 桶等。你回答的内容会被写进 samconfig.toml,之后在项目根目录直接执行 sam deploy 就能复现同样的部署——这就是"一次配置、重复部署"的来源。

熟悉之后,可以用显式参数部署:

`bash sam deploy \ --stack-name my-serverless-app-prod \ --region ap-east-1 \ --parameter-overrides Stage=prod \ --capabilities CAPABILITY_IAM \ --no-confirm-changeset `

三个参数需要解释:

- --capabilities CAPABILITY_IAM 是必须的。 SAM 要替你创建执行角色,CloudFormation 要求你显式承认"这个模板会创建 IAM 资源"。忘了它,部署会直接失败并提示缺少 capabilities,这是第二个高频坑。 - --stack-name 建议带环境后缀。 同一个模板部署两次(-dev 和 -prod)就是两个完全独立的栈,各自有独立的资源与账单,互不影响。这是"一套模板多环境"最省事的做法。 - --region 决定一切。 区域不同,资源不互通、价格可能有差异、延迟更是天差地别。面向中国大陆用户的无服务器 API,香港 ap-east-1 通常是延迟最优的起点。

关于产物桶:sam deploy 会先把 sam build 的产物上传到 S3,再由 CloudFormation 从 S3 读取并部署。默认会自动创建一个由 SAM 托管的桶;你也可以用 --s3-bucket your-bucket 指定自己的桶,便于统一管理权限与生命周期。

开发期请改用 sam sync。 它只同步发生变化的部分(函数代码直接更新、基础设施变化才走完整 CloudFormation 流程),把迭代时间从"每次两三分钟"压到"十几秒":

`bash sam sync --stack-name my-serverless-app-dev --watch `

加 --watch 后,本地文件一保存,云端立刻更新。但有一条纪律必须写清楚:sam sync 只用于开发环境。 它会绕过变更集直接改资源,生产环境应当走标准 sam deploy,保留可审计、可回滚的变更集记录——这一点在多人协作时尤其重要。

八、价格与真实单价:SAM 不收费,但资源收费

再强调一次:SAM 与 SAM CLI 本身不产生任何费用,账单全部来自它创建出来的资源。一个最典型的无服务器应用 = API Gateway + Lambda,下面是两张官方定价页上的公开单价(美东 us-east-1 口径),直接做成表方便你对着算。

Lambda 部分:

| 计费项 | x86 单价 | Arm(Graviton)单价 | |---|---|---| | 请求数 | $0.20 / 百万次 | $0.20 / 百万次 | | 执行时长(首 60 亿 GB-秒/月) | $0.0000166667 / GB-秒 | $0.0000133334 / GB-秒 | | 执行时长(次 90 亿 GB-秒/月) | $0.000015 / GB-秒 | $0.0000120001 / GB-秒 | | 执行时长(150 亿 GB-秒以上) | $0.0000133334 / GB-秒 | $0.0000106667 / GB-秒 | | 临时存储(512 MB 以上部分) | $0.0000000309 / GB-秒 | 同左 | | 预置并发 Provisioned Concurrency | $0.0000041667 / GB-秒 | 同左 | | 响应流式传输 | $0.008 / GB | 同左 |

关于 Arm 的一点提醒:请求费和存储费两者相同,只有"执行时长"这一项 Arm 比 x86 低 20%($0.0000133334 相对 $0.0000166667)。所以对"每次执行很短、调用次数极大"的函数,换 Arm 省得有限;而对单次执行时间长的函数,换架构的效果就很明显。

API Gateway 部分:

| API 类型 | 单价 | 免费额度(仅新客户注册后 12 个月内) | |---|---|---| | HTTP API | $1.00 / 百万次(首 3 亿次),超出后 $0.90 / 百万次 | 100 万次/月 | | REST API | $3.50 / 百万次(首 3.33 亿次),超出后阶梯降到 $2.80 / $2.38 | 100 万次/月 | | WebSocket API | $1.00 / 百万消息 + $0.25 / 百万连接分钟 | 100 万消息 + 75 万连接分钟/月 |

对比一下就明白官方为什么把 HTTP API 列为新项目首选:HTTP API 与 REST API 的单价差 3.5 倍($1.00 对 $3.50 每百万次)。只有当你确实需要 REST API 独有能力——API Key 与使用计划、请求参数校验、边缘优化端点、集成 AWS WAF——时才值得为这 3.5 倍差价买单。

接下来是最容易被误判的一条:两类免费额度的有效期口径不一样。

- Lambda 的免费额度是"每月"给的:每月 100 万次请求 + 40 万 GB-秒,定价页表述为 "The free tier includes one million requests and 400,000 GB-seconds per month",没有附加 12 个月的限制。 - API Gateway 的免费额度明确标注了期限:官方原文写明这些免费额度 "only available to new AWS customers, and are available for 12 months following your AWS sign-up date"。

写预算时务必把这两者分开算:一年之后 API 网关部分的 100 万次就不再免费,而 Lambda 部分仍然按月给额度。很多"无服务器几乎不要钱"的说法,恰恰是把这两件事混为一谈了。

还有两条容易被忽略的边界:

1. 预置并发不享受免费额度。 官方原文:The Lambda free tier does not apply to functions enabling Provisioned Concurrency。你开了预置并发,这部分按 $0.0000041667 / GB-秒全额计费。 2. 临时存储只有 512 MB 免费。 你可以把函数临时存储配到最高 10,240 MB,但超出 512 MB 的部分按 GB-秒计费。

最后一个"隐藏账单主角"提醒:如果你的 API 返回大文件(图片、PDF、视频切片),真正吃掉预算的往往不是函数执行费,而是数据传出与流式传输费。 函数执行费按毫秒算,动辄只有几美元;而每 GB 传出的单价是 0.008~0.09 美元量级,量一上来就是主要成本。做架构决策时先估算"每月传出多少 GB",比先优化函数代码更有效。

九、成本测算:三档典型场景一个月到底花多少钱

下面三个算例都用第九节之前的官方单价自行折算,属于示意算例而非报价,你可以把数字换成自己的量再算一遍。

场景 A:个人博客 / 小工具 API。 每月 10 万次请求,每次执行 100 毫秒,内存 512 MB(Arm)。

| 计费项 | 用量 | 折算 | 费用 | |---|---|---|---| | Lambda 执行时长 | 10 万 × 0.1 秒 × 0.5 GB = 5,000 GB-秒 | 未超 40 万免费额度 | $0 | | Lambda 请求数 | 10 万次 | 未超 100 万免费额度 | $0 | | API Gateway(HTTP API) | 10 万次 | 未超 100 万免费额度 | $0 | | 合计(第一年) | | | $0 / 月 |

第二年起,因为 API 网关的 100 万次免费额度已过期,这 10 万次按 $1.00 / 百万次计费,约 $0.10 / 月——依旧可以忽略不计。这也是"个人项目用无服务器最划算"的真实原因。

场景 B:小团队 SaaS 后端。 每月 300 万次请求,每次执行 120 毫秒,内存 1536 MB(x86)。这个量级正好与 Lambda 官方定价页给出的算例同口径,可以直接对照:

| 计费项 | 计算过程 | 费用 | |---|---|---| | 执行时长 | 300 万 × 0.12 秒 × 1.5 GB = 540,000 GB-秒,减 40 万免费额度后剩 140,000 GB-秒 | 约 $2.33 | | 请求数 | 300 万 − 100 万免费 = 200 万次 | $0.40 | | API Gateway(HTTP API) | 约 200 万次(超出免费额度部分) | 约 $2.00 | | 合计 | | 约 $4.73 / 月 |

官方对该算例本身给出的函数侧结论是 $2.73 / 月($2.33 计算费 + $0.40 请求费),与上表前两行完全一致;加上 API 网关部分才是完整的端到端成本。第二年起 API 网关那 300 万次全额计费,总额约 $6.73 / 月。

场景 C:同样负载改用 Arm 能省多少。 保持场景 B 的其他条件不变,只把架构换成 arm64:

| 架构 | 执行时长单价 | 超出部分的费用 | |---|---|---| | x86 | $0.0000166667 / GB-秒 | 140,000 × 单价 ≈ $2.33 | | Arm | $0.0000133334 / GB-秒 | 140,000 × 单价 ≈ $1.87 |

仅此一项就省下约 20%,而代码通常不用改一行(Python、Node.js 等解释型语言几乎零成本迁移)。唯一需要检查的是依赖里有没有 x86 专用二进制包——有就先用 x86,或者换用提供 Arm 版本依赖的库。

这三档算例想说明的结论是:无服务器的成本敏感度极高,但敏感点不在函数执行费,而在"有没有超出免费额度"以及"数据传出多少"。 一个月 10 万次请求和一个月 300 万次请求,前者是 0 元、后者不到 5 元——中间没有"起步价"这一说,这正是无服务器对小项目最友好的地方。

十、省钱五招

第一招:新项目默认 arm64。 执行时长单价直接低 20%,解释型语言基本零改造。上面场景 C 已经算给你看了。

第二招:先用 sam local 调,别拿云端当测试环境。 本地调试不产生任何 AWS 费用。很多人无服务器账单超预期,根因是"用生产环境反复测试"——每次调 API 都产生真实的请求费与执行费,还有可能触发数据传出的钱。

第三招:能选 HTTP API 就别选 REST API。 单价差 3.5 倍。先问自己是否真的需要 API Key、使用计划(Usage Plan)、请求校验、WAF 集成这四样 REST 独有能力;不需要,就用 HTTP API。

第四招:给内存找"费用拐点"。 Lambda 的内存与 CPU 是成比例放大的,内存调大后执行时间可能成倍缩短,结果是 GB-秒(也就是费用)未必增加。业界常用做法是用 Lambda Power Tuning 这类工具把同一函数在多个内存档位各跑一遍,找出"总费用最低"的那个档位——它往往不是最低内存的那一档。

第五招:用 Compute Savings Plans 覆盖长期稳定的计算时长。 按 AWS Savings Plans 的官方口径,Compute Savings Plans 的适用范围覆盖 Lambda 与 Fargate 等计算类用量。如果你的无服务器负载已经稳定运行了几个月、且短期不打算迁移,可以考虑用承诺用量换折扣;本站另有专文展开:

- AWS Savings Plans 深度攻略

另外别忘了免费计划的三个"保鲜期"设定:免费计划本身有效期 6 个月,账户额度(最高 $200,注册即得 $100,探索基础服务再得最多 $100)需要在创建账号后 12 个月内用完,而且一旦账号加入 AWS Organizations 或建立 Control Tower landing zone,免费额度立即失效、免费计划自动升级为付费计划。所以顺序应当是:先把免费实验做完,再考虑并入组织做统一账单治理。

十一、八个必踩过的坑(附排错思路)

坑 1:模板漏写 Transform: AWS::Serverless-2016-10-31。 这是 SAM 新手最高频的失败原因。少了这一行,CloudFormation 不认 AWS::Serverless::Function 这个资源类型,部署直接报错。排错口诀:凡是报"无法识别的资源类型 / Unrecognized resource types",先看模板第二行。

坑 2:忘了 --capabilities CAPABILITY_IAM。 报错信息里会出现 requires capabilities 的字样。SAM 要创建执行角色与策略,CloudFormation 必须得到你的显式授权。首次部署用 sam deploy --guided 时会被问到,"以后别再问"的选项会把它写进 samconfig.toml,这也是为什么引导模式值得走一次。

坑 3:CodeUri 路径写错。 CodeUri 是相对于模板文件所在目录的路径,不是相对你执行命令的目录。改成多函数结构后(每个函数一个子目录),这里的路径最容易错位。现象是 sam build 报找不到源码或依赖文件。

坑 4:本地跑通、线上 500 / 403。 这是 SAM 教程里最经典、也最容易被误判成"SAM 有 bug"的一类问题。根因几乎总是权限差异:sam local 用的是你本机 AWS 凭证(权限通常很大,甚至是管理员),而线上函数用的是 SAM 自动生成的执行角色(默认只有写日志这类基础权限)。所以函数里一旦调用了 S3、DynamoDB、SQS,本地能通、线上就 AccessDenied。正确做法不是给角色挂 AdministratorAccess,而是用 AWS::Serverless::Connector 或显式策略把函数真正需要的那一个动作加进去。

坑 5:环境变量只写在本地。 只在 env.json 里配了变量、忘了写进模板的 Environment.Variables,结果本地正常、线上函数读到空值。判断标准还是那句:以模板声明为准,env.json 只是本地覆盖层。

坑 6:把 sam sync 用到生产环境。 sam sync 会跳过变更集直接改资源,速度快但不可审计、缺少变更预览。开发环境用它提升效率没问题,生产环境务必回到 sam deploy。

坑 7:把两类免费额度的期限搞混。 API Gateway 的 100 万次/月只在开户后 12 个月内有效;Lambda 的 100 万次请求 + 40 万 GB-秒是按月给的长期额度;而预置并发完全不享受免费额度。做第一年预算和第二年会得出两个截然不同的结论。

坑 8:一边用免费计划、一边把账号并入组织。 只要账号加入 AWS Organizations,或建立了 Control Tower landing zone,免费额度立即失效、免费计划自动转为付费计划,并且此后不再具备获得免费额度的资格。另外免费计划到期后的处理也要提前知道:AWS 会关闭账号,数据保留 90 天,期间可以升级到付费计划找回;超过 90 天未升级,账号及其全部内容会被永久删除。所以"要不要为了统一账单把新号并入组织"这个问题,答案永远是:等免费实验做完再说。

十二、常见问题 FAQ

Q: 用 SAM 会不会多花一笔钱? A: 不会。SAM 是开源框架、SAM CLI 是本地工具,两者都不计费;CloudFormation 也不按资源数量收费。你的账单完全等于"所创建的 Lambda、API Gateway、DynamoDB 等资源的用量费用",与管理方式无关。

Q: SAM 和 Serverless Framework、AWS CDK 有什么区别,该选哪个? A: 三者都是 IaC,差别在抽象层次与厂商绑定。SAM 是 AWS 官方原生的无服务器框架,模板是 CloudFormation 超集,部署与权限模型完全走 AWS 原生路径,最适合"只用 AWS + 以 Lambda/API 为主"的项目。Serverless Framework 跨云支持更好、生态插件多,但抽象层更厚、排错时更黑盒。CDK 用编程语言(TypeScript/Python 等)生成 CloudFormation,适合逻辑复杂、需要循环与条件判断的场景。只做 AWS 无服务器,从 SAM 开始门槛最低。

Q: 不用 Docker 能用 SAM 吗? A: 部分可以。sam validate、sam build(不带 --use-container)、sam deploy 都不需要 Docker;但 sam local invoke 与 sam local start-api 的完整功能需要 Docker 来模拟 Lambda 运行时。没有 Docker 时,本地调试这条路基本走不通。

Q: 我已经在控制台手工建了函数,能迁到 SAM 管理吗? A: SAM 没有一键导入控制台已有函数的能力。两条可行路径:一是把这些资源改写成 SAM 模板后,用 CloudFormation 的资源导入(resource import)功能收编进栈;二是干脆以 SAM 模板为新的唯一真实来源重建,确认无误后删除手工资源。函数代码不必重写,要重写的是"描述它的那几十行 YAML"。 数量不多时,第二条路更干净。

Q: 一套模板怎么管理测试和生产两套环境? A: 三层配合:Parameters 声明可变项(如 Stage)、samconfig.toml 存两套部署配置、--stack-name 带环境后缀(如 -dev / -prod)。这样同一份模板会生成两个互不干扰的栈,各有独立的资源与账单。

Q: 面向中国大陆用户,选哪个区域? A: 国际站账号首选香港 ap-east-1——地理距离近、延迟通常最低。要注意的是:AWS 中国(北京、宁夏)区域由本地合作伙伴独立运营,国际站账号无法直接使用,需要单独的账号体系。若你的用户主要在中国大陆而你又必须用国际站,请把"区域延迟"和"跨境链路稳定性"一起纳入评估,必要时配合 CDN 做前置加速。

Q: 怎么随时知道免费额度用了多少、会不会被扣费? A: 三个入口配合看:控制台首页的 Cost and Usage 组件会显示免费计划到期日与额度余额;Billing and Cost Management 控制台的 Credits 页面能查到额度到期时间;程序化追踪可以用 GetAccountPlanState 这类 API。想更主动一点,就配一个预算告警,阈值设在 1 美元——这是防止"免费账号悄悄扣费"最便宜的一道保险(本站有专门的预算与告警实战)。

Q: 函数冷启动慢怎么办? A: 按性价比排序:把函数包和依赖体积压到最小(这是收益最高、成本最低的一招)→ 内存档位适当调大(CPU 也同步变大,初始化更快)→ 使用 arm64(相同价格下性能通常更好)→ 最后才考虑预置并发(它能让延迟稳定在两位数毫秒,但不享受免费额度,且按 GB-秒持续计费)。

十三、总结:把无服务器应用变成一个可版本化的对象

回到文章开头那个问题——为什么"会写 Lambda"和"能上线 Lambda"是两回事?因为前者是代码能力,后者是工程能力。SAM 补上的正是后者:它让一个无服务器应用拥有了一份可以进 Git、可以 review、可以一键重建、可以按环境分身的定义文件。

如果要给一条从零上手的路径,建议就按本文的顺序走一遍:

1. 装齐依赖(AWS CLI v2 + SAM CLI + Docker),用 aws sts get-caller-identity 确认凭证可用; 2. sam init 起项目,新项目默认选 arm64; 3. sam build + sam local invoke 在本机把逻辑调通——这一步不花一分钱; 4. sam deploy --guided 首次部署到香港或你选定的区域,把配置固化进 samconfig.toml; 5. 开发期用 sam sync --watch,生产发布回到 sam deploy 保留变更集; 6. 最后配一个 1 美元的预算告警,给免费账号上一道保险。

三条最值得记住的结论,也是这篇文章与满街"复制粘贴式教程"的区别所在:

- SAM 本身不收费,但两类免费额度的有效期完全不同——Lambda 的 100 万次请求 + 40 万 GB-秒是按月给的长期额度,API Gateway 的 100 万次只在开户后 12 个月内有效,且预置并发不享受免费额度。做预算时把它们分开算,结论才不会跑偏。 - 用 Arm(Graviton)换 20% 的执行时长单价,而且只在"执行时长"这一项上省——请求费与存储费两者相同,所以清单里那些"每次只跑 50 毫秒"的小函数换架构收益有限。 - sam local 是完全免费的调试通道。在免费额度有限的账号上,先把逻辑在本地调通再上云,是省钱与提效同时发生的一件事。

> 声明:本文价格数据采集于 2026 年 9 月,来自 AWS 官方定价页公开单价(美东 us-east-1 口径),仅作参考;实际费用随区域、用量阶梯与官方调价变动,请以 AWS 官网与控制台结算页的实时价格为准。文中成本测算均为示意算例,不构成报价。除特别标注外,金额单位均为美元(USD)。

> ⚠️ 文中价格为 2026 年参考价,实际费用随区域和官方调价变动,请以 AWS 官网为准。

> 🚀 需要 AWS 国际版账号?通过 3.chengzicloud.cloud 获取最新注册教程与专属优惠,助你轻松上云。

相关阅读

- AWS Lambda 无服务器 API 实战 - AWS CloudFormation 基础设施即代码实战 - AWS API Gateway 深度实战 - AWS Step Functions 工作流编排实战 - AWS 2026 最新免费套餐注册教程:避免被扣费的 5 个关键设置 - AWS Budgets 预算告警实战

> 本文由 3.chengzicloud.cloud 提供,点击访问首页了解更多