绑定VPC的AWS Lambda通过SES发邮件失败的解决方案咨询
解决绑定VPC的AWS Lambda调用SES发送邮件的问题
一、修复SES接口端点超时问题(优先推荐)
你之前创建的是email-smtp接口端点,但AWS SDK调用SES用的是REST API而非SMTP协议,这是核心错误。需要创建ses类型的接口端点,具体操作:
- 创建
com.amazonaws.eu-west-1.ses接口端点:- 进入VPC控制台,选择「端点」>「创建端点」
- 服务类别选「AWS服务」,搜索
ses,选择对应区域的com.amazonaws.eu-west-1.ses(接口类型) - 勾选Lambda所在的子网,选择合适的安全组
- 配置安全组:
- Lambda所在安全组:允许出站到TCP 443端口,目标指向SES接口端点的安全组或前缀列表
- SES接口端点安全组:允许入站来自Lambda安全组的TCP 443流量
- 配置路由表:
在Lambda子网关联的路由表中,添加一条路由,目标为SES的前缀列表(pl-xxxx),下一跳为创建的SES接口端点
完成后,绑定VPC的Lambda就能直接通过VPC端点调用SES API,无需依赖互联网。
二、解决无VPC的SendMail Lambda调用问题
无VPC的Lambda默认自带互联网访问权限,不会继承调用方的VPC配置,你的问题大概率出在权限或调用逻辑上,按以下步骤排查:
- 检查主Lambda的执行角色权限:
确保主Lambda的IAM角色拥有lambda:InvokeFunction权限,目标资源为SendMail Lambda的ARN,示例策略:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:eu-west-1:你的账号ID:function:SendMail函数名" } ] } - 检查SendMail Lambda的配置:
- 确认SendMail Lambda未绑定任何VPC
- 确认其执行角色包含:
AWSLambdaBasicExecutionRole(用于写入CloudWatch日志)- SES发送权限:
ses:SendEmail或ses:SendRawEmail,目标资源可设为*或指定的邮箱/域名
- 查看CloudWatch日志定位问题:
- 打开SendMail Lambda的日志组,确认函数是否被成功触发
- 如果日志显示SES调用失败,检查权限或邮箱验证状态(SES要求发件人邮箱/域名必须验证)
- 如果SendMail没有日志,说明主Lambda的调用请求未送达,检查调用代码是否正确,示例Python代码:
import boto3 import json lambda_client = boto3.client('lambda', region_name='eu-west-1') def lambda_handler(event, context): # 调用SendMail Lambda,异步调用用InvocationType='Event' response = lambda_client.invoke( FunctionName='SendMail函数名', InvocationType='RequestResponse', Payload=json.dumps({"to_email": "xxx@example.com", "subject": "Test", "body": "Hello"}).encode('utf-8') ) payload = json.loads(response['Payload'].read()) return payload
- 避免同步调用超时:
若主Lambda在VPC中,同步调用无VPC的Lambda可能因网络延迟超时,可改为异步调用(InvocationType='Event'),主Lambda无需等待执行结果,直接返回,SendMail在后台独立运行。
三、替代方案(不推荐,除非上述方法无效)
给绑定VPC的Lambda所在子网配置NAT网关,让Lambda通过NAT网关访问互联网调用SES API:
- 创建NAT网关并分配弹性IP
- 在Lambda子网的路由表中添加默认路由(
0.0.0.0/0),下一跳指向NAT网关 - 确保NAT网关所在的公网子网有互联网访问权限
此方法会产生额外的NAT网关费用,不如VPC端点经济。
内容的提问来源于stack exchange,提问作者Conrad
相关产品推荐
相关产品推荐

