Como trabalhar com camadas em Ruby para funções do Lambda - AWS Lambda

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:

  1. 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.

  2. Criar a camada no Lambda.

  3. Adicionar a camada às suas funções.

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/x.x.x (onde x.x.x é sua versão do Ruby, por exemplo 3.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
  1. 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'
  2. Instale os gems no diretório vendor/bundle usando o Bundler:

    bundle config set --local path vendor/bundle bundle install
  3. Copie os gems instalados para a estrutura de diretórios exigida pelo Lambdaruby/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. Crie um arquivo .zip do conteúdo da camada:

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

    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 ou Bundler.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, pg, mysql2, sqlite3 e ffi. Esses gems devem ser criados em um ambiente Linux compatível com o runtime do Lambda.

Para criar uma camada usando gems com extensões nativas
  1. Crie um Gemfile.

    exemplo Gemfile
    source 'https://rubygems.org' gem 'nokogiri' gem 'httparty'
  2. 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/
  3. 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 ou Bundler.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
  1. Crie a estrutura de diretório necessária para sua camada:

    mkdir -p ruby/lib
  2. 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
  3. Crie um arquivo .zip do conteúdo da camada:

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

    A estrutura de diretórios do arquivo zip deve ser assim:

    ruby/              
    └── lib/
        └── order_validator.rb
  4. 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 ou Bundler.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.

AWS CLI

Execute o comando da AWS CLI publish-layer-version para criar a camada do Lambda:

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

O parâmetro runtimes compatíveis é opcional. Quando especificado, o Lambda usa esse parâmetro para filtrar camadas no console do Lambda.

Console
Para criar uma camada (console)
  1. Abra a página Layers (Camadas) do console do Lambda.

  2. Escolha Criar camada.

  3. Escolha Carregar um arquivo .zip e depois carregue o arquivo .zip que você criou anteriormente.

  4. (Opcional) Para ver quais são os runtimes compatíveis, escolha o runtime Ruby que corresponde à versão do Ruby que você usou para criar a camada.

  5. Escolha Criar.

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

AWS CLI

Para anexar a camada à função, execute o comando da AWS CLI update-function-configuration . Para o parâmetro --layers use o ARN da camada. O ARN deve especificar a versão (por exemplo, arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1). Para obter mais informações, consulte Camadas e versões da camada.

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"

A opção cli-binary-format será necessária se você estiver usando a AWS CLI versão 2. Para que essa seja a configuração padrão, execute aws configure set cli-binary-format raw-in-base64-out. Para obter mais informações, consulte A AWS CLI comporta opções de linha de comando globais no Guia do usuário da AWS Command Line Interface versão 2.

Console
Para adicionar uma camada a uma função
  1. Abra a página Funções do console do Lambda.

  2. Escolha a função.

  3. Role a tela para baixo até a seção Camadas e depois escolha Adicionar uma camada.

  4. Em Escolher uma camada, selecione Camadas personalizadas e depois escolha a camada.

    nota

    Se você não adicionou um runtime compatível ao criar a camada, ela não estará listada aqui. Em vez disso, você pode especificar o ARN da camada.

  5. Escolha Adicionar.

Aplicação de amostra

Para obter mais exemplos de como usar camadas do Lambda, consulte a aplicação de amostra layer-ruby no repositório AWS Lambda Developer Guide do GitHub. Essa aplicação inclui uma camada que contém a biblioteca zinfo. Após criar a camada, você pode implantar e invocar as funções correspondentes para confirmar que ela funciona conforme o esperado.