Como trabalhar com camadas em Ruby para funções do Lambda
Use camadas do Lambda para empacotar o código e as dependências que você quiser reutilizar em várias funções. As camadas geralmente contêm dependências de biblioteca, um runtime personalizado ou arquivos de configuração. A criação de uma camada envolve três etapas gerais:
-
Empacotar o conteúdo da sua camada. Isso significa criar um arquivo .zip contendo as dependências que você deseja usar em suas funções.
-
Criar a camada no Lambda.
-
Adicionar a camada às suas funções.
Tópicos
Empacotar o conteúdo da sua camada
Para criar uma camada, reúna os pacotes em um arquivo .zip que atenda aos seguintes requisitos:
-
Crie a camada usando a mesma versão do Ruby que você planeja usar para a função do Lambda. Por exemplo, se você criar a camada para o Ruby 3.4, use o runtime do Ruby 3.4 para a função.
-
O arquivo .zip da camada deve usar uma destas estruturas de diretório:
-
ruby/gems/
(ondex.x.x
x.x.x
é sua versão do Ruby, por exemplo3.4.0
) -
ruby/lib
Para obter mais informações, consulte Caminhos da camada para cada runtime do Lambda.
-
-
Os pacotes da camada devem ser compatíveis com o Linux. As funções do Lambda são executadas no Amazon Linux.
Você pode criar camadas que contenham gems em Ruby de terceiros ou seus próprios módulos e classes em Ruby. Muitos gems em Ruby populares contêm extensões nativas (código C) que devem ser compiladas para o ambiente Lambda Linux.
Os gems em Ruby puras contêm somente código Ruby e não precisam de compilação. Essas geas são mais simples de empacotar e trabalhar em diferentes plataformas.
Para criar uma camada usando os gems em Ruby Pure
-
Crie um
Gemfile
para especificar os gems em Ruby Pure que você deseja incluir na sua camada:exemplo Gemfile
source 'https://rubygems.org' gem 'tzinfo'
-
Instale os gems no diretório
vendor/bundle
usando o Bundler:bundle config set --local path vendor/bundle bundle install
-
Copie os gems instalados para a estrutura de diretórios exigida pelo 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/
-
Crie um arquivo .zip do conteúdo da camada:
A estrutura de diretórios do arquivo zip deve ser assim:
ruby/ └── gems/ └── 3.4.0/ ├── gems/ │ ├── concurrent-ruby-1.3.5/ │ └──
tzinfo-2.0.6/
├── specifications/ ├── cache/ ├── build_info/ └── (other bundler directories)nota
Você deve exigir cada gem individualmente em seu código de função. Você pode usar
bundler/setup
ouBundler.require
. Para obter mais informações, consulte Como usar gems de camadas em uma função.
Muitos gems em Ruby populares contêm extensões nativas (código C) que devem ser compiladas para a plataforma de destino. Gemas populares com extensões nativas incluem nokogiri
Para criar uma camada usando gems com extensões nativas
-
Crie um
Gemfile
.exemplo Gemfile
source 'https://rubygems.org' gem 'nokogiri' gem 'httparty'
-
Use o Docker para criar os gems em um ambiente Linux compatível com o Lambda. Especifique uma imagem base da AWS em seu Dockerfile:
exemplo Dockerfile para Ruby 3.4
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/ -
Crie a imagem e extraia a camada:
docker build -t ruby-layer-builder . docker run --rm -v $(pwd):/output --entrypoint cp ruby-layer-builder layer.zip /output/
Isso cria os gems no ambiente Linux correto e copia o arquivo
layer.zip
para o diretório local. A estrutura de diretórios do arquivo zip deve ser assim: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)nota
Você deve exigir cada gem individualmente em seu código de função. Você pode usar
bundler/setup
ouBundler.require
. Para obter mais informações, consulte Como usar gems de camadas em uma função.
Para criar uma camada usando seu próprio código
-
Crie a estrutura de diretório necessária para sua camada:
mkdir -p ruby/lib
-
Crie seus módulos de Ruby no diretório
ruby/lib
. O exemplo de módulo a seguir valida os pedidos confirmando que eles contêm as informações necessárias.exemplo 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
-
Crie um arquivo .zip do conteúdo da camada:
A estrutura de diretórios do arquivo zip deve ser assim:
ruby/ └── lib/ └── order_validator.rb
-
Na função, exija e use os módulos. Você deve exigir cada gem individualmente em seu código de função. Você pode usar
bundler/setup
ouBundler.require
. Para obter mais informações, consulte Como usar gems de camadas em uma função. Exemplo: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
Você pode usar os seguinte evento de testepara invocar a função:
{ "body": "{\"product_id\": \"ABC123\", \"quantity\": 2, \"priority\": \"express\"}" }
Resposta esperada:
{ "statusCode": 200, "body": "{\"message\":\"Order validated successfully\",\"order\":{\"product_id\":\"ABC123\",\"quantity\":2,\"shipping_priority\":\"express\"}}" }
Criar a camada no Lambda
Você pode publicar a camada usando a AWS CLI ou o console do Lambda.
Como usar gems de camadas em uma função
Em seu código de função, você deve exigir explicitamente cada gem que você deseja usar. Comandos do bundler, como bundler/setup
e Bundler.require
não são compatíveis. Veja como usar corretamente os gems de uma camada em uma função do Lambda:
# 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
Adicionar a camada à função
Aplicação de amostra
Para obter mais exemplos de como usar camadas do Lambda, consulte a aplicação de amostra layer-ruby