Node.js Lambda 関数のレイヤーを操作する - AWS Lambda

Node.js Lambda 関数のレイヤーを操作する

Lambda レイヤーを使用して、複数の関数間で再利用するコードおよび依存関係をパッケージ化できます。レイヤーには通常、ライブラリの依存関係、カスタムランタイム、または設定ファイルが含まれています。レイヤーの作成には、次の 3 つの一般的な手順が含まれます。

  1. レイヤーコンテンツのパッケージ化。これは、関数で使用する依存関係を含む .zip ファイルアーカイブを作成することを意味します。

  2. Lambda でレイヤーを作成します。

  3. レイヤーを関数に追加します。

レイヤーコンテンツのパッケージ化

レイヤーを作成するには、次の要件を満たす .zip ファイルのアーカイブにパッケージをバンドルします。

  • Lambda 関数に使用するのと同じ Node.js バージョンを使用してレイヤーを構築します。例えば、Node.js 22 を使用してレイヤーを構築する場合、関数に Node.js 22 ランタイムを使用してください。

  • Layer の .zip ファイルは、次のいずれかのディレクトリ構造を使用する必要があります。

    • nodejs/node_modules

    • nodejs/nodeX/node_modules (X は Node.js バージョン。例: node22

    詳細については、「各 Lambda ランタイムのレイヤーパス」を参照してください。

  • レイヤーのパッケージは Linux と互換性がある必要があります。Lambda 関数は Amazon Linux 上で動作します。

  • レイヤーにネイティブバイナリまたは実行可能ファイルが含まれている場合は、関数と同じアーキテクチャ (x86_64 または arm64) をターゲットにする必要があります。

npm がインストールされたサードパーティ Node ライブラリ (axioslodash など) か、ユーザー独自の JavaScript モジュールやパッケージのいずれかを含むレイヤーを作成できます。

npm パッケージを使用してレイヤーを作成する方法
  1. 必要なディレクトリ構造を作成し、パッケージを直接インストールします。

    mkdir -p nodejs npm install --prefix nodejs lodash axios

    このコマンドは、Lambda が必要とする構造である nodejs/node_modules ディレクトリにパッケージを直接インストールします。

    注記

    ネイティブ依存関係またはコンポーネントを含むパッケージの場合 (例: sharpbcrypt など)、それらが Lambda Linux 環境および関数のアーキテクチャと互換性があることを確認してください。--platform フラグを使用する必要がある場合があります。

    npm install --prefix nodejs --platform=linux --arch=x64 sharp

    より複雑なネイティブ依存関係については、Lambda ランタイムに一致する Linux 環境でコンパイルする必要がある場合があります。この目的で Docker を使用できます。

  2. レイヤーコンテンツを圧縮します。

    Linux/macOS
    zip -r layer.zip nodejs/
    PowerShell
    Compress-Archive -Path .\nodejs -DestinationPath .\layer.zip

    .zip ファイルのディレクトリ構造は次のようになります。

    nodejs/              
    └── node_modules/
        ├── lodash/
        ├── axios/
        └── (dependencies of the other packages)
    注記

    zip ファイルには、ルートレベルに nodejs ディレクトリを含み、その中に node_modules ディレクトリがあることを確認してください。この構造により、Lambda がパッケージを検出し、インポートできます。

ユーザー独自のコードを使用してレイヤーを作成する方法
  1. レイヤーに必要なディレクトリ構造を作成します。

    mkdir -p nodejs/node_modules/validator
  2. 独自のモジュールをインポートする方法を定義するため、package.json ファイルを作成します。

    例 package.json
    { "name": "validator", "version": "1.0.0", "type": "module", "main": "index.mjs" }
  3. JavaScript モジュール ファイルを作成します。

    例 nodejs/node_modules/validator/index.mjs
    export function validateOrder(orderData) { // Validates an order and returns formatted data const requiredFields = ['productId', 'quantity']; // Check required fields const missingFields = requiredFields.filter(field => !(field in orderData)); if (missingFields.length > 0) { throw new Error(`Missing required fields: ${missingFields.join(', ')}`); } // Validate quantity const quantity = orderData.quantity; if (!Number.isInteger(quantity) || quantity < 1) { throw new Error('Quantity must be a positive integer'); } // Format and return the validated data return { productId: String(orderData.productId), quantity: quantity, shippingPriority: orderData.priority || 'standard' }; } export function formatResponse(statusCode, body) { // Formats the API response return { statusCode: statusCode, body: JSON.stringify(body) }; }
  4. レイヤーコンテンツを圧縮します。

    Linux/macOS
    zip -r layer.zip nodejs/
    PowerShell
    Compress-Archive -Path .\nodejs -DestinationPath .\layer.zip

    .zip ファイルのディレクトリ構造は次のようになります。

    nodejs/              
    └── node_modules/
        └── validator/
            ├── package.json
            └── index.mjs
  5. 関数内でモジュールをインポートして使用します。例:

    import { validateOrder, formatResponse } from 'validator'; export const handler = async (event) => { try { // Parse the order data from the event body const orderData = JSON.parse(event.body || '{}'); // Validate and format the order const validatedOrder = validateOrder(orderData); return formatResponse(200, { message: 'Order validated successfully', order: validatedOrder }); } catch (error) { if (error instanceof Error && error.message.includes('Missing required fields')) { return formatResponse(400, { error: error.message }); } return formatResponse(500, { error: 'Internal server error' }); } };

    次のテストイベントを使用して関数を呼び出すことができます。

    { "body": "{\"productId\": \"ABC123\", \"quantity\": 2, \"priority\": \"express\"}" }

    予想されるレスポンス

    { "statusCode": 200, "body": "{\"message\":\"Order validated successfully\",\"order\":{\"productId\":\"ABC123\",\"quantity\":2,\"shippingPriority\":\"express\"}}" }

Lambda でレイヤーを作成する

AWS CLI または Lambda コンソールを使用して、レイヤーを発行できます。

AWS CLI

publish-layer-version AWS CLI コマンドを実行して Lambda レイヤーを作成します。

aws lambda publish-layer-version --layer-name my-layer --zip-file fileb://layer.zip --compatible-runtimes nodejs22.x

互換性のあるランタイムパラメータの使用は任意です。指定すると、Lambda はこのパラメータを使用して Lambda コンソールのレイヤーをフィルタリングします。

Console
レイヤーを作成するには (コンソール)
  1. Lambda コンソールの [Layers (レイヤー)] ページを開きます。

  2. [Create layer] (レイヤーの作成) を選択します。

  3. [.zip ファイルをアップロードする]を選択し、前の手順で作成しておいた .zip アーカイブをアップロードします。

  4. (オプション) [互換性のあるランタイム]には、レイヤーの構築に使用した Node.js バージョンに対応する Node.js ランタイムを選択できます。

  5. [作成] を選択します。

レイヤーを関数に追加する

AWS CLI

レイヤーを関数にアタッチするには、update-function-configuration AWS CLI コマンドを実行します。--layers パラメータには、レイヤー ARN を使用します。ARN はバージョンを指定する必要があります (arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1 など)。詳細については、「レイヤーとレイヤーバージョン」を参照してください。

aws lambda update-function-configuration --function-name my-function --cli-binary-format raw-in-base64-out --layers "arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1"

AWS CLI バージョン 2 を使用している場合、cli-binary-format オプションは必須です。これをデフォルト設定にするには、aws configure set cli-binary-format raw-in-base64-out を実行します。詳細については、バージョン 2 の AWS Command Line Interface ユーザーガイドの「AWS CLI でサポートされているグローバルコマンドラインオプション」を参照してください。

Console
関数にレイヤーを追加する方法
  1. Lambda コンソールの [関数] ページを開きます。

  2. 関数を選択します。

  3. [レイヤー] セクションまで下にスクロールし、[レイヤーの追加] を選択します。

  4. [レイヤーの選択][カスタムレイヤー] を選択し、レイヤーを指定します。

    注記

    レイヤーの作成時に互換性のあるランタイムを追加しなかった場合、レイヤーはここには表示されません。代わりにレイヤー ARN を指定できます。

  5. [Add] (追加) を選択します。

サンプルアプリ

Lambda レイヤーの使用方法のその他の例については、「AWS Lambda デベロッパーガイド」の GitHub リポジトリ内の layer-nodejs サンプルアプリケーションを参照してください。このアプリケーションには、lodash ライブラリを含むレイヤーが含まれています。各レイヤーを作成したら、対応する関数をデプロイして呼び出し、レイヤーが期待どおりに動作するかどうかを確認できます。