Ruby Lambda 関数のレイヤーを操作する
Lambda レイヤーを使用して、複数の関数間で再利用するコードおよび依存関係をパッケージ化できます。レイヤーには通常、ライブラリの依存関係、カスタムランタイム、または設定ファイルが含まれています。レイヤーの作成には、次の 3 つの一般的な手順が含まれます。
-
レイヤーコンテンツのパッケージ化。これは、関数で使用する依存関係を含む .zip ファイルアーカイブを作成することを意味します。
-
Lambda でレイヤーを作成します。
-
レイヤーを関数に追加します。
レイヤーコンテンツのパッケージ化
レイヤーを作成するには、次の要件を満たす .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 を使用してレイヤーを作成する
-
Gemfile
を作成して、レイヤーに含める pure Ruby gem を指定します。例 Gemfile
source 'https://rubygems.org' gem 'tzinfo'
-
Bundler を使用して、gem を
vendor/bundle
ディレクトリにインストールします。bundle config set --local path vendor/bundle bundle install
-
インストールされた 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/
-
レイヤーコンテンツを圧縮します。
.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/setup
やBundler.require
を使用することはできません。詳細については、「関数内のレイヤーからの gem の使用」を参照してください。
一般的な Ruby gem の多くには、ネイティブ拡張機能 (C コード) が含まれています。これらは、ターゲットプラットフォーム用にコンパイルする必要があります。ネイティブ拡張機能が含まれる一般的な gem には、nokogiri
ネイティブ拡張機能が含まれる gem を使用してレイヤーを作成する
-
Gemfile
を作成します。例 Gemfile
source 'https://rubygems.org' gem 'nokogiri' gem 'httparty'
-
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/ -
イメージを構築し、レイヤーを抽出します。
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/setup
やBundler.require
を使用することはできません。詳細については、「関数内のレイヤーからの gem の使用」を参照してください。
ユーザー独自のコードを使用してレイヤーを作成する方法
-
レイヤーに必要なディレクトリ構造を作成します。
mkdir -p ruby/lib
-
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
-
レイヤーコンテンツを圧縮します。
.zip ファイルのディレクトリ構造は次のようになります。
ruby/ └── lib/ └── order_validator.rb
-
関数内でモジュールを require し、使用します。関数コードでは、各 gem を個別に require する必要があります。
bundler/setup
やBundler.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 コンソールを使用して、レイヤーを発行できます。
関数内のレイヤーからの gem の使用
関数コードでは、使用する各 gem を明示的に require する必要があります。bundler/setup
や Bundler.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
レイヤーを関数に追加する
サンプルアプリ
Lambda レイヤーのさらなる使用方法例については、「AWS Lambda デベロッパーガイド」の GitHub リポジトリにある layer-nodejs