AWS Lambda デプロイパッケージをアップロードしようとすると、「アクセス許可が拒否されました」と「unable to import module」というエラーが表示されます。
簡単な説明
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 OS ライブラリと 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 に変更します。詳細については、Wikipedia ウェブサイトの「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 *
-
新しいデプロイパッケージをアップロードします。