Ruby Lambda 関数のレイヤーを操作する - AWS Lambda

Ruby Lambda 関数のレイヤーを操作する

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

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

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

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

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

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

  • Lambda 関数に使用する予定のものと同じ Ruby バージョンを使用するレイヤーを作成する。例えば、Ruby 3.4 向けのレイヤーを作成する場合は、関数にも Ruby 3.4 ランタイムを使用します。

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

    • ruby/gems/x.x.x (x.x.x は、3.4.0 などの Ruby バージョン)

    • ruby/lib

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

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

サードパーティーの Ruby gem、または独自の Ruby モジュールとクラスが含まれるレイヤーを作成できます。一般的な Ruby gem の多くには、ネイティブ拡張機能 (C コード) が含まれています。これらは、Lambda Linux 環境用にコンパイルする必要があります。

Pure Ruby gem には Ruby コードのみが含まれており、コンパイルは必要ありません。これらの gem は、さまざまなプラットフォームでより簡単にパッケージ化して使用できます。

Pure Ruby gem を使用してレイヤーを作成する
  1. Gemfile を作成して、レイヤーに含める pure Ruby gem を指定します。

    例 Gemfile
    source 'https://rubygems.org' gem 'tzinfo'
  2. Bundler を使用して、gem を vendor/bundle ディレクトリにインストールします。

    bundle config set --local path vendor/bundle bundle install
  3. インストールされた gem を、Lambda が必要とするディレクトリ構造 (ruby/gems/3.4.0) にコピーします。

    mkdir -p ruby/gems/3.4.0 cp -r vendor/bundle/ruby/3.4.0*/* ruby/gems/3.4.0/
  4. レイヤーコンテンツを圧縮します。

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

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

    ruby/              
    └── gems/
        └── 3.4.0/
            ├── gems/
            │   ├── concurrent-ruby-1.3.5/
            │   └── tzinfo-2.0.6/
            ├── specifications/
            ├── cache/
            ├── build_info/
            └── (other bundler directories)
    注記

    関数コードでは、各 gem を個別に require する必要があります。bundler/setupBundler.require を使用することはできません。詳細については、「関数内のレイヤーからの gem の使用」を参照してください。

一般的な Ruby gem の多くには、ネイティブ拡張機能 (C コード) が含まれています。これらは、ターゲットプラットフォーム用にコンパイルする必要があります。ネイティブ拡張機能が含まれる一般的な gem には、nokogiripgmysql2sqlite3ffi などがあります。これらの gem は、Lambda ランタイムとの互換性がある Linux 環境内で構築する必要があります。

ネイティブ拡張機能が含まれる gem を使用してレイヤーを作成する
  1. Gemfile を作成します。

    例 Gemfile
    source 'https://rubygems.org' gem 'nokogiri' gem 'httparty'
  2. Docker を使用して、Lambda との互換性がある Linux 環境内で gem を構築します。Dockerfile で AWS ベースイメージを指定します。

    例 Ruby 3.4 用の Dockerfile
    FROM public.ecr.aws/lambda/ruby:3.4 # Copy Gemfile COPY Gemfile ./ # Install system dependencies for native extensions RUN dnf update -y && \ dnf install -y gcc gcc-c++ make # Configure bundler and install gems RUN bundle config set --local path vendor/bundle && \ bundle install # Create the layer structure RUN mkdir -p ruby/gems/3.4.0 && \ cp -r vendor/bundle/ruby/3.4.0*/* ruby/gems/3.4.0/ # Create the layer zip file RUN zip -r layer.zip ruby/
  3. イメージを構築し、レイヤーを抽出します。

    docker build -t ruby-layer-builder . docker run --rm -v $(pwd):/output --entrypoint cp ruby-layer-builder layer.zip /output/

    そうすることで、正しい Linux 環境に gem が構築され、ローカルディレクトリに layer.zip ファイルがコピーされます。.zip ファイルのディレクトリ構造は次のようになります。

    ruby/
    └── gems/
        └── 3.4.0/
            ├── gems/
            │   ├── bigdecimal-3.2.2/
            │   ├── csv-3.3.5/
            │   ├── httparty-0.23.1/
            │   ├── mini_mime-1.1.5/
            │   ├── multi_xml-0.7.2/
            │   ├── nokogiri-1.18.8-x86_64-linux-gnu/
            │   └── racc-1.8.1/
            ├── build_info/
            ├── cache/
            ├── specifications/
            └── (other bundler directories)
    注記

    関数コードでは、各 gem を個別に require する必要があります。bundler/setupBundler.require を使用することはできません。詳細については、「関数内のレイヤーからの gem の使用」を参照してください。

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

    mkdir -p ruby/lib
  2. ruby/lib ディレクトリに Ruby モジュールを作成します。次のモジュール例は、必要な情報が含まれていることを確認して注文をバリデーションします。

    例 ruby/lib/order_validator.rb
    require 'json' module OrderValidator class ValidationError < StandardError; end def self.validate_order(order_data) # Validates an order and returns formatted data required_fields = %w[product_id quantity] # Check required fields missing_fields = required_fields.reject { |field| order_data.key?(field) } unless missing_fields.empty? raise ValidationError, "Missing required fields: #{missing_fields.join(', ')}" end # Validate quantity quantity = order_data['quantity'] unless quantity.is_a?(Integer) && quantity > 0 raise ValidationError, 'Quantity must be a positive integer' end # Format and return the validated data { 'product_id' => order_data['product_id'].to_s, 'quantity' => quantity, 'shipping_priority' => order_data.fetch('priority', 'standard') } end def self.format_response(status_code, body) # Formats the API response { statusCode: status_code, body: JSON.generate(body) } end end
  3. レイヤーコンテンツを圧縮します。

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

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

    ruby/              
    └── lib/
        └── order_validator.rb
  4. 関数内でモジュールを require し、使用します。関数コードでは、各 gem を個別に require する必要があります。bundler/setupBundler.require を使用することはできません。詳細については、「関数内のレイヤーからの gem の使用」を参照してください。例:

    require 'json' require 'order_validator' def lambda_handler(event:, context:) begin # Parse the order data from the event body order_data = JSON.parse(event['body'] || '{}') # Validate and format the order validated_order = OrderValidator.validate_order(order_data) OrderValidator.format_response(200, { message: 'Order validated successfully', order: validated_order }) rescue OrderValidator::ValidationError => e OrderValidator.format_response(400, { error: e.message }) rescue => e OrderValidator.format_response(500, { error: 'Internal server error' }) end end

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

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

    予想されるレスポンス

    { "statusCode": 200, "body": "{\"message\":\"Order validated successfully\",\"order\":{\"product_id\":\"ABC123\",\"quantity\":2,\"shipping_priority\":\"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 ruby3.4

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

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

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

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

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

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

関数内のレイヤーからの gem の使用

関数コードでは、使用する各 gem を明示的に require する必要があります。bundler/setupBundler.require などの Bundler コマンドはサポートされていません。以下は、Lambda 関数内のレイヤーから gem を適切に使用する方法です。

# Correct: Use explicit requires for each gem require 'nokogiri' require 'httparty' def lambda_handler(event:, context:) # Use the gems directly doc = Nokogiri::HTML(event['html']) response = HTTParty.get(event['url']) # ... rest of your function end # Incorrect: These Bundler commands will not work # require 'bundler/setup' # Bundler.require

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

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 ライブラリが含まれるレイヤーがあります。各レイヤーを作成したら、対応する関数をデプロイして呼び出し、レイヤーが期待どおりに動作するかどうかを確認できます。