概述
AWS Lambda 是无服务器(Serverless)计算服务:上传函数代码,由 AWS 按事件触发执行,按实际运行时长计费,无需管理虚拟机。
适合短任务、事件驱动、低频定时作业(配合 EventBridge Scheduler)、轻量 API(API Gateway)、消息消费(SQS / SNS)等场景。不适合长时间常驻进程或持续高 CPU 负载。
核心概念
| 概念 | 说明 |
|---|---|
| Function | 一个部署单元:代码 + 运行时 + 配置(内存、超时、环境变量) |
| Handler | 入口函数名,格式 文件名.函数名,如 lambda_function.handler |
| Runtime | 运行环境,如 python3.13、nodejs22.x |
| Execution Role | Lambda 扮演的 IAM Role,决定函数内能调用哪些 AWS API |
| Event | 触发时传入的 JSON 载荷(Scheduler、SNS、API Gateway 等格式不同) |
| Context | 运行时元数据(剩余超时时间、请求 ID 等) |
| Resource-based policy | 挂在函数上的策略,声明谁可以调用本函数(aws_lambda_permission) |
ARN 格式
函数 ARN 示例:
arn:aws:lambda:ap-northeast-1:123456789012:function:enx-api-backup
版本与别名会追加后缀(:1、:prod);日常在 Scheduler、SNS 订阅里通常用未限定版本的函数 ARN。
权限模型(两层)
Lambda 涉及两类 IAM,容易混淆:
| 类型 | 谁配置 | 解决什么问题 |
|---|---|---|
| Execution Role | 函数自身 role 字段 |
函数出站能做什么(写日志、调 SSM、读 S3) |
| Resource policy | aws_lambda_permission 等 |
谁可以调用这个函数(Scheduler、SNS、API Gateway) |
EventBridge Scheduler ──(resource policy: lambda:InvokeFunction)──► Lambda
│
▼
Execution Role
(ssm:SendCommand, logs:PutLogEvents, …)
│
▼
EC2 / SSM / …
- Execution Role 信任策略 Principal 为
lambda.amazonaws.com(见 AWS IAM) - 调用方(如 Scheduler)还需要自己的 Role 带
lambda:InvokeFunction;函数侧通常再加一条aws_lambda_permission限定source_arn
Handler 约定
以 Python 为例,入口签名固定为 handler(event, context):
def handler(event, context):
# event:调用方传入的 JSON(Scheduler 的 input、SNS 的 Records 等)
# context:剩余毫秒数 context.get_remaining_time_in_millis() 等
return {"status": "ok"}
- 同步调用:返回值会回传给调用方
- 异步调用:返回值无意义;失败走重试 / DLQ(见 AWS SQS)
- 超时或未捕获异常:Lambda 记为失败,CloudWatch 有
Errors指标和日志
常见触发方式
| 触发源 | 典型用途 | 相关笔记 |
|---|---|---|
| EventBridge Scheduler | 定时任务 | EventBridge Scheduler |
| SNS | 告警转发(邮件旁路 Telegram 等) | AWS SNS |
| SQS | 队列消费、异步解耦 | AWS SQS |
| API Gateway / ALB | HTTP API | — |
| S3 / DynamoDB 等 | 对象上传、表变更 | — |
同一函数可被多个触发源订阅;每次调用是独立并发执行(受账户并发上限约束)。
实践:定时备份 + SNS 通知
东京 EC2 上的 w10n-config 栈里有两个 Lambda:
| 函数 | 作用 |
|---|---|
enx-api-backup |
Scheduler 每周触发 → SSM Run Command 在 EC2 跑备份脚本 |
sns-telegram-notify |
SNS Topic 订阅 → 把告警推到 Telegram(可选) |
链路示意:
Scheduler (cron 周日 03:00 UTC)
→ enx-api-backup (120s timeout)
→ SSM send_command + 轮询 GetCommandInvocation
→ 失败时 Scheduler DLQ → CloudWatch Alarm → SNS → 邮件 / Telegram Lambda
SNS (enx-api-backup-alerts)
├─ email
└─ lambda: sns-telegram-notify
enx-api-backup 核心逻辑(节选):用 Execution Role 调 SSM,并在超时前轮询命令状态:
def handler(event, context):
instance_id = os.environ["EC2_INSTANCE_ID"]
ssm = boto3.client("ssm")
resp = ssm.send_command(
InstanceIds=[instance_id],
DocumentName="AWS-RunShellScript",
Parameters={"commands": ["/usr/local/bin/enx-api-backup.sh"]},
)
# … 轮询 get_command_invocation 直到 Success / Failed …
注意:Scheduler 的 DLQ 只收纳「调 Lambda 失败」;Lambda 已成功返回但 SSM/脚本失败,不会进 Scheduler DLQ,需在函数内抛错或另设告警。
OpenTofu 要点
# Execution Role
resource "aws_iam_role" "lambda_enx_backup" {
name = "lambda-enx-backup-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "lambda.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
resource "aws_cloudwatch_log_group" "lambda_enx_backup" {
name = "/aws/lambda/enx-api-backup"
retention_in_days = 30
}
resource "aws_lambda_function" "enx_backup" {
function_name = "enx-api-backup"
role = aws_iam_role.lambda_enx_backup.arn
runtime = "python3.13"
handler = "lambda_function.handler"
filename = data.archive_file.enx_api_backup.output_path
source_code_hash = data.archive_file.enx_api_backup.output_base64sha256
timeout = 120
environment {
variables = {
EC2_INSTANCE_ID = aws_instance.ec2_tokyo.id
}
}
depends_on = [aws_cloudwatch_log_group.lambda_enx_backup]
}
# 允许 Scheduler 调用(resource-based policy)
resource "aws_lambda_permission" "scheduler_enx_backup" {
statement_id = "AllowEventBridgeScheduler"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.enx_backup.function_name
principal = "scheduler.amazonaws.com"
source_arn = aws_scheduler_schedule.enx_backup.arn
}
部署代码常用 archive_file 把 lambda_function.py 打成 zip;改代码后 source_code_hash 变化会触发函数更新。
SNS 触发 Lambda 时同样需要 aws_lambda_permission(principal = "sns.amazonaws.com")+ aws_sns_topic_subscription(protocol = "lambda")。
日志与排错
Lambda 自动把 stdout / stderr 写到 CloudWatch Logs,Log group 名为 /aws/lambda/<函数名>(见 CloudWatch)。
# 手动同步调用(测试)
aws lambda invoke \
--region ap-northeast-1 \
--function-name enx-api-backup \
/tmp/out.json && cat /tmp/out.json
# 查看配置
aws lambda get-function-configuration --function-name enx-api-backup
# 跟踪日志
aws logs tail /aws/lambda/enx-api-backup --since 1h --follow
配置建议
| 项 | 说明 |
|---|---|
| timeout | 设为略大于最坏情况耗时;轮询 SSM 时要留余量 |
| memory | 影响 CPU 配额;默认 128 MB 对轻量脚本够用,可按冷启动与耗时调高 |
| 环境变量 | 非机密配置(实例 ID);密钥用 Secrets Manager / SSM Parameter Store |
| Log retention | 预建 Log group 并设 retention_in_days,避免日志无限堆积 |
| 并发 | 账户有区域并发上限;预留并发可保证关键函数不被挤占(额外费用) |
计费(概要)
- 请求:按调用次数
- 持续时间:按 GB-秒(内存 × 执行时间)
- 免费档:每月有一定请求量与 GB-秒(具体见官网,低频 homelab 任务通常可忽略)
Scheduler、SSM、S3 等其它服务另计,不算在 Lambda 账单条目里。