Arbeiten mit Ebenen für Ruby Lambda-Funktionen
Verwenden Sie Lambda-Ebenen, um Code und Abhängigkeiten zu bündeln, die Sie für mehrere Funktionen wiederverwenden möchten. Ebenen enthalten üblicherweise Bibliotheksabhängigkeiten, eine benutzerdefinierte Laufzeit oder Konfigurationsdateien. Das Erstellen einer Ebene umfasst drei allgemeine Schritte:
-
Verpacken Ihres Ebeneninhalts. Dies bedeutet, dass Sie ein .zip-Dateiarchiv erstellen, das die Abhängigkeiten enthält, die Sie in Ihren Funktionen verwenden möchten.
-
Erstellen Sie die Ebene in Lambda.
-
Fügen Sie die Ebene zu Ihren Funktionen hinzu.
Themen
Verpacken Ihres Ebeneninhalts
Um eine Ebene zu erstellen, bündeln Sie Ihre Pakete in einem ZIP-Dateiarchiv, das die folgenden Anforderungen erfüllt:
-
Erstellen Sie die Ebene mithilfe derselben Version von Ruby, die Sie für die Lambda-Funktion verwenden möchten. Wenn Sie beispielsweise Ihre Ebene für Ruby 3.4 erstellen, verwenden Sie die Laufzeit Ruby 3.4 für Ihre Funktion.
-
Die ZIP-Datei Ihrer Ebene muss eine der folgenden Verzeichnisstrukturen verwenden:
-
ruby/gems/(wobeix.x.xx.x.xIhre Ruby-Version ist, z. B.3.4.0) -
ruby/lib
Weitere Informationen finden Sie unter Ebenenpfade für jede Lambda-Laufzeit.
-
-
Die Pakete in Ihrer Ebene müssen mit Linux kompatibel sein. Lambda-Funktionen werden auf Amazon Linux ausgeführt.
Sie können Ebenen erstellen, die entweder Ruby-Gems von Drittanbietern oder Ihre eigenen Ruby-Module und -Klassen enthalten. Viele beliebte Ruby-Gems enthalten native Erweiterungen (C-Code), die für die Lambda-Linux-Umgebung kompiliert werden müssen.
Reine Ruby-Gems enthalten nur Ruby-Code und müssen nicht kompiliert werden. Diese Gems lassen sich einfacher verpacken und funktionieren plattformübergreifend.
So erstellen Sie eine Ebene mit reinen Ruby-Gems
-
Erstellen Sie eine
Gemfile, um die reinen Ruby-Gems anzugeben, die Sie in Ihre Ebene aufnehmen möchten:Beispiel Gemfile
source 'https://rubygems.org' gem 'tzinfo' -
Installieren Sie die Gems mit Bundler in einem
vendor/bundle-Verzeichnis:bundle config set --local path vendor/bundle bundle install -
Kopieren Sie die installierten Gems in die Verzeichnisstruktur, die Lambda benötigt (
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/ -
Verpacken Sie den Ebeneninhalt:
Die Verzeichnisstruktur Ihrer ZIP-Datei sollte wie folgt aussehen:
ruby/ └── gems/ └── 3.4.0/ ├── gems/ │ ├── concurrent-ruby-1.3.5/ │ └──tzinfo-2.0.6/├── specifications/ ├── cache/ ├── build_info/ └── (other bundler directories)Anmerkung
Sie müssen jede Gem einzeln in Ihrem Funktionscode als erforderlich festlegen. Sie können nicht
bundler/setupoderBundler.requireverwenden. Weitere Informationen finden Sie unter Verwenden von Gems aus Ebenen in einer Funktion.
Viele beliebte Ruby-Gems enthalten native Erweiterungen (C-Code), die für die Zielplattform kompiliert werden müssen. Beliebte Gems mit nativen Erweiterungen sind unter anderem nokogiri
So erstellen Sie eine Ebene mit Gems mit nativen Erweiterungen
-
Erstellen eines
Gemfile.Beispiel Gemfile
source 'https://rubygems.org' gem 'nokogiri' gem 'httparty' -
Verwenden Sie Docker, um die Gems in einer Linux-Umgebung zu erstellen, die mit Lambda kompatibel ist. Geben Sie ein AWS-Basisabbild in Ihrem Dockerfile an:
Beispiel Dockerfile für Ruby 3.4
FROMpublic.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/ -
Erstellen Sie das Bild und extrahieren Sie die Ebene:
docker build -t ruby-layer-builder . docker run --rm -v $(pwd):/output --entrypoint cp ruby-layer-builder layer.zip /output/Dadurch werden die Gems in der richtigen Linux-Umgebung erstellt und die
layer.zip-Datei in Ihr lokales Verzeichnis kopiert. Die Verzeichnisstruktur Ihrer ZIP-Datei sollte wie folgt aussehen: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)Anmerkung
Sie müssen jede Gem einzeln in Ihrem Funktionscode als erforderlich festlegen. Sie können nicht
bundler/setupoderBundler.requireverwenden. Weitere Informationen finden Sie unter Verwenden von Gems aus Ebenen in einer Funktion.
So erstellen Sie eine Ebene mithilfe Ihres eigenen Codes
-
Erstellen Sie die erforderliche Verzeichnisstruktur für Ihre Ebene:
mkdir -p ruby/lib -
Erstellen Sie Ihre Ruby-Module im
ruby/lib-Verzeichnis. Das folgende Beispielmodul validiert Bestellungen, indem es überprüft, ob sie die erforderlichen Informationen enthalten.Beispiel 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 -
Verpacken Sie den Ebeneninhalt:
Die Verzeichnisstruktur Ihrer ZIP-Datei sollte wie folgt aussehen:
ruby/ └── lib/ └── order_validator.rb -
Fordern Sie in Ihrer Funktion die Module an und verwenden Sie sie. Sie müssen jede Gem einzeln in Ihrem Funktionscode als erforderlich festlegen. Sie können nicht
bundler/setupoderBundler.requireverwenden. Weitere Informationen finden Sie unter Verwenden von Gems aus Ebenen in einer Funktion. Beispiel: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 endSie können das folgende Testereignis verwenden, um die Funktion aufzurufen:
{ "body": "{\"product_id\": \"ABC123\", \"quantity\": 2, \"priority\": \"express\"}" }Erwartete Antwort:
{ "statusCode": 200, "body": "{\"message\":\"Order validated successfully\",\"order\":{\"product_id\":\"ABC123\",\"quantity\":2,\"shipping_priority\":\"express\"}}" }
Erstellen Sie die Ebene in Lambda
Sie können Ihre Ebene entweder über die AWS CLI oder die Lambda-Konsole veröffentlichen.
Verwenden von Gems aus Ebenen in einer Funktion
In Ihrem Funktionscode müssen Sie jedes Gem, das Sie verwenden möchten, explizit als erforderlich festlegen. Bundler-Befehle wie bundler/setup und Bundler.require werden nicht unterstützt. So verwenden Sie Gems aus einer Ebene in einer Lambda-Funktion:
# 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
Fügen Sie die Ebene zu Ihrer Funktion hinzu
Beispiel-App
Weitere Beispiele für die Verwendung von Lambda-Ebenen finden Sie in der Beispielanwendung layer-ruby