如何在SAM构建时将本地commoncode模块导入AWS Lambda函数?
这个问题我之前也碰到过!SAM默认的构建逻辑只会打包每个Lambda目录下的文件,以及通过requirements.txt声明的依赖,所以你的commoncode模块不会自动被包含进去。有两种常用的解决办法,看你更倾向哪种:
方法一:通过requirements.txt引入本地模块
这种方法适合小型项目,直接把共享模块当作依赖安装到每个Lambda的环境中:
给commoncode模块添加打包配置
在commoncode目录下创建一个setup.py文件(或者用更现代的pyproject.toml),让pip能识别这是一个可安装的Python包:from setuptools import setup, find_packages setup( name="commoncode", version="0.1.0", packages=find_packages(), description="Shared utilities for Lambda functions", )在每个Lambda的requirements.txt中添加路径
因为lambda1和lambda2的目录和commoncode是同级的,所以在lambda1/requirements.txt和lambda2/requirements.txt里添加:../commoncode重新构建项目
运行sam build,此时SAM会在构建每个Lambda时,自动将commoncode模块安装到对应的依赖目录中,打包时就会包含进去了。
方法二:使用Lambda Layers管理共享代码
如果你的共享模块会被多个Lambda复用,更推荐用Lambda Layers——这是AWS专门为共享代码设计的方案,避免重复打包,也方便统一更新:
在template.yaml中定义Layer资源
打开你的template.yaml,添加一个Layer资源(注意替换成你实际的Python运行时版本):Resources: CommonCodeLayer: Type: AWS::Lambda::LayerVersion Properties: LayerName: commoncode-utils-layer Description: Shared common utilities for Lambda functions ContentUri: ./commoncode/ CompatibleRuntimes: - python3.10 # 匹配你的Lambda运行时 LicenseInfo: MIT让Lambda函数引用这个Layer
在每个Lambda函数的配置里添加Layers字段,引用刚才定义的Layer:Lambda1Function: Type: AWS::Serverless::Function Properties: CodeUri: lambda1/ Handler: app.lambda_handler Runtime: python3.10 Layers: - !Ref CommonCodeLayer Lambda2Function: Type: AWS::Serverless::Function Properties: CodeUri: lambda2/ Handler: app2.lambda_handler Runtime: python3.10 Layers: - !Ref CommonCodeLayer构建并部署
运行sam build,SAM会单独构建这个Layer,然后每个Lambda都会在运行时加载这个Layer里的代码,这样你的commoncode模块就能被正常导入了。
另外补充一下:本地运行正常是因为你的Python环境已经把项目根目录加入了sys.path,所以能找到commoncode;但SAM构建时是在隔离的虚拟环境中打包,默认只会处理当前Lambda目录下的内容,所以必须显式声明依赖或者用Layer来引入。
内容的提问来源于stack exchange,提问作者Phil Lachmann

