我在上传 AWS Lambda 部署包时遇到“permission denied”或“unable to import module”错误。
简短描述
Lambda 需要对代码文件和部署包中所有依赖库具备全局读取权限。如果未使用正确的安全权限配置 Lambda 部署包,则在您尝试上传文件时,Lambda 就会返回错误。在持续集成应用程序创建部署包时,常常会发生这类 permission denied 和 unable to import module 错误。
对于解释型运行时(例如 Python),部署包中文件的正确权限为 644。对于部署包中的文件夹,正确的权限为 755。
对于编译后的运行时(例如 Go),部署包中可执行文件和目录的正确权限以 Unix 权限数字表示法表示为 755。
**注意:**由于 Lambda 使用 POSIX 权限,因此在构建 Lambda 部署包时最好使用与 POSIX 兼容的操作系统(OS)。兼容的操作系统包括 Linux、Unix 或 macOS。如果构建环境与 Lambda 运行时环境中的权限模型平等,就可以降低出现权限问题的可能性。
要以 Windows 用户身份修复权限问题,请完成以下一种任务来设置 Linux 环境:
解决方法
找到导致错误的文件或文件夹
错误消息中可能未明确提示错误原因,取决于编写 Lambda 函数代码时使用的编程语言。
例如,Node.js 函数错误消息会列出错误源的文件或文件夹名称。但是,Python 函数错误消息不会列出错误源的文件或文件夹名称。
Node.js Lambda 函数 permission denie 错误示例
{ "errorMessage": "EACCES: permission denied, open '/var/task/index.js'", "errorType": "Error",
"stackTrace": [
"Object.fs.openSync (fs.js:641:18)",
"Object.fs.readFileSync (fs.js:509:33)",
"Object.Module._extensions..js (module.js:578:20)",
"Module.load (module.js:487:32)",
"tryModuleLoad (module.js:446:12)",
"Function.Module._load (module.js:438:3)",
"Module.require (module.js:497:17)",
"require (internal/module.js:20:19)"
]
}
Python Lambda 函数 unable to import module 错误示例
“Unable to import module 'index': No module named index”
要解决此错误,请参阅如何解决我在 Python 中运行 Lambda 代码时遇到的“Unable to import module”错误?
如果您的 Lambda 部署包不是 Amazon Linux 2 或 Amazon Linux 2023,则必须与 Amazon Linux 版本兼容。为此,请在安装软件包时使用以下参数。以下示例在 Lambda 函数所在的同一文件夹中使用了 Python 3.12 操作系统和 NumPy 库:
pip3 install --platform manylinux2014_x86_64 --target . --python-version 3.12 --only-binary=:all: numpy
根据您的用例,调整以下值:
- 平台 manylinux2014_x86_64 值可指定软件包的平台。
- python-version 3.12 值表示该软件包与指定的 Python 版本兼容。根据 Lambda 中的目标 Python 运行时版本调整该值。
- 参数 only-binary=:all 会指示 pip 仅下载二进制文件。此参数能确保软件包与 Lambda 运行时环境兼容。
缺少所需权限的外部库出现 Python Lambda 函数错误示例
“Unable to import module 'index': No module named requests”
要检查部署包 .zip 文件中所有文件和文件夹的权限,请在命令行界面(CLI)中运行 zipinfo 命令:
zipinfo lambda-package.zip
**注意:**将 lambda-package.zip 替换为部署包 .zip 文件名。
zipinfo 命令响应示例
Archive: lambda-package.zipZip file size: 305 bytes, number of entries: 1-r-------- 3.0 unx 188 tx defN 21-Feb-13 20:48 example.py
1 file, 188 bytes uncompressed, 135 bytes compressed: 28.2%
**注意:**在前面的示例中,example.py 的权限为 -r--------,或者以 Unix 权限数字表示法表示为 400。将该文件的权限更新为 644。有关更多信息,请参阅维基百科网站上的 ](https://en.wikipedia.org/wiki/File-system_permissions#Notation_of_traditional_Unix_permissions)Notation of traditional Unix permissions[。
更新部署包的权限
**注意:**以下命令仅适用于 Linux、Unix 和 macOS。
-
要将部署包中的文件和文件夹解压到临时文件夹,请在 CLI 中运行以下命令:
mkdir temp-folder; unzip lambda-package.zip -d temp-folder ;cd temp-folder;ls -l
**注意:**请将 lambda-package.zip 替换为部署包的文件名,将 temp-folder 替换为临时文件夹的名称。
-
更新库文件的权限。
**注意:**要让所有用户都能执行目录且能读取解压部署包中的所有文件和文件夹,请运行 chmod 命令:
$ sudo chmod 644 $(find -type f) && chmod 755 $(find -type d)
要使解压的部署包文件在编译后的运行时可执行,请运行以下命令:
$ chmod 755 -R
-
修复权限后,运行以下命令将文件和文件夹重新打包为新的 .zip 文件:
zip -r new-lambda-package.zip *
-
上传新的部署包。