如何對上傳 Lambda 部署套件時的「permission denied」或「unable to import module」錯誤進行疑難排解?

2 分的閱讀內容
0

當我上傳 AWS Lambda 部署套件時,會出現「permission denied」或「unable to import module」錯誤。

簡短說明

Lambda 需要對程式碼檔案和部署套件中任何相依資源庫的全域讀取權限。如果您沒有使用正確的安全性權限設定 Lambda 部署套件,則 Lambda 會在您嘗試上傳檔案時傳回錯誤。在連續整合應用程式建立部署套件時,通常會發生拒絕權限無法匯入模組錯誤。

對於解譯的執行時期,例如 Python,部署套件中檔案的正確權限為 644。對於部署套件中的資料夾,正確的權限為 755

對於編譯的執行時期,例如 Go,部署套件中可執行檔案和目錄的正確權限在 Unix 權限數字表示法中為 755

**注意:**由於 Lambda 使用 POSIX 權限,因此建立 Lambda 部署套件時,使用相容 POSIX 的作業系統 (OS) 是最佳做法。合規的作業系統包括 Linux、Unix 或 macOS。建置環境中的權限模型與 Lambda 的執行時期環境之間的平等可能會降低權限問題的機率。

若要以 Windows 使用者分身修正權限問題,請完成下列其中一項工作來設定 Linux 環境:

解決方法

找到造成錯誤的檔案或資料夾

根據您用來編寫 Lambda 函數程式碼的程式設計語言,錯誤訊息可能不會顯示明確的錯誤原因。

例如,Node.js 函數錯誤訊息會列出錯誤來源的檔案或資料夾名稱。但是,Python 函數錯誤訊息不會列出錯誤來源的檔案或資料夾名稱。

Node.js Lambda 函數權限拒絕錯誤的範例

{  "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 '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

根據您的使用情況,調整下列值:

  • platform 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

**注意:**使用您的部署套件 .zip 檔案名稱取代 lambda-package.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。如需詳細資訊,請參閱 Wikipedia 網站上的傳統 Unix 權限表示法

更新部署套件的權限

**注意:**下列命令僅適用於 Linux、Unix 和 macOS。

  1. 若要將部署套件內的檔案和資料夾解壓縮至暫存資料夾,請在 CLI 中執行下列命令:

    mkdir temp-folder; unzip lambda-package.zip -d temp-folder ;cd temp-folder;ls -l

    **注意:**使用您的部署套件的檔案名稱取代 lambda-package.zip,用暫存資料夾的名稱取代 temp-folder

  2. 更新函式庫檔案的權限
    **注意:**若要讓任何使用者讀取目錄可執行檔案,以及解壓縮部署套件中的所有檔案和資料夾,請執行 chmod 命令:

    $ sudo chmod 644 $(find -type f) && chmod 755 $(find -type d)

    若要讓解壓縮的部署套件檔案對編譯的執行時期可執行,請執行下列命令:

    $ chmod 755 -R
  3. 修正權限之後,請執行下列命令,將檔案和資料夾重新封裝為新的 .zip 檔案:

    zip -r new-lambda-package.zip *
  4. 上傳新的部署套件

AWS 官方
AWS 官方已更新 5 個月前