Uso de capas para funciones de Lambda en Ruby - AWS Lambda

Uso de capas para funciones de Lambda en Ruby

Utilice capas de Lambda para empaquetar el código y las dependencias que desee reutilizar en varias funciones. Las capas suelen contener dependencias de biblioteca, un tiempo de ejecución personalizado o archivos de configuración. La creación de una capa implica tres pasos generales:

  1. Empaquete el contenido de su capa. Esto significa crear un archivo de archivo. zip que contenga las dependencias que desea usar en sus funciones.

  2. Cree la capa en Lambda.

  3. Agregue la capa a sus funciones.

Empaquete el contenido de su capa.

Para crear una capa, agrupe sus paquetes en un archivo .zip que cumpla con los siguientes requisitos:

  • Cree la capa con la misma versión de Ruby que tiene previsto usar para la función de Lambda. Por ejemplo, si crea una capa para Ruby 3.4, utilice el tiempo de ejecución de Ruby 3.4 para su función.

  • El archivo .zip de su capa debe usar una de estas estructuras de directorios:

    • ruby/gems/x.x.x (donde x.x.x es su versión de Ruby, por ejemplo 3.4.0)

    • ruby/lib

    Para obtener más información, consulte Rutas de capa para cada tiempo de ejecución de Lambda.

  • Los paquetes de la capa deben ser compatibles con Linux. Las funciones de Lambda se ejecutan en Amazon Linux.

Puede crear capas que contengan gemas de Ruby de terceros o sus propios módulos y clases de Ruby. Muchas gemas populares de Ruby contienen extensiones nativas (código C) que deben compilarse para el entorno de Lambda de Linux.

Las gemas puras de Ruby contienen solo código de Ruby y no requieren compilación. Estas gemas son más fáciles de empaquetar y funcionan en diferentes plataformas.

Creación de una capa usando gemas puras de Ruby
  1. Cree un Gemfile para especificar las gemas puras de Ruby que desea incluir en su capa:

    ejemplo Archivo Gemfile
    source 'https://rubygems.org' gem 'tzinfo'
  2. Instale las gemas en el directorio vendor/bundle mediante Bundler:

    bundle config set --local path vendor/bundle bundle install
  3. Copie las gemas instaladas a la estructura de directorios que Lambda requiere 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. Comprima en formato zip el contenido de la capa:

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

    La estructura de directorios del archivo .zip debería ser similar a la siguiente:

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

    Debe incluir cada gema de forma individual en el código de la función. No puede utilizar bundler/setup o Bundler.require. Para obtener más información, consulte Utilización de gemas de capas en una función.

Muchas gemas de Ruby populares contienen extensiones nativas (código C) que deben compilarse para la plataforma de destino. Entre las gemas más populares con extensiones nativas se encuentran nokogiri, pg, mysql2, sqlite3 y ffi. Estas gemas se deben crear en un entorno de Linux que sea compatible con el tiempo de ejecución de Lambda.

Creación de una capa con gemas con extensiones nativas
  1. Creación de una Gemfile.

    ejemplo Archivo Gemfile
    source 'https://rubygems.org' gem 'nokogiri' gem 'httparty'
  2. Utilice Docker para crear las gemas en un entorno de Linux que sea compatible con Lambda. Especifique una imagen base de AWS en su Dockerfile:

    ejemplo 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. Cree la imagen y extraiga la capa:

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

    Esto crea las gemas en el entorno de Linux correcto y copia el archivo layer.zip a su directorio local. La estructura de directorios del archivo .zip debería ser similar a la siguiente:

    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

    Debe incluir cada gema de forma individual en el código de la función. No puede utilizar bundler/setup o Bundler.require. Para obtener más información, consulte Utilización de gemas de capas en una función.

Creación de una capa con su propio código
  1. Cree la estructura del directorio necesario para su capa:

    mkdir -p ruby/lib
  2. Cree sus módulos de Ruby en el directorio ruby/lib. El siguiente módulo de ejemplo valida los pedidos mediante la confirmación de que contienen la información requerida.

    ejemplo 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. Comprima en formato zip el contenido de la capa:

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

    La estructura de directorios del archivo .zip debería ser similar a la siguiente:

    ruby/              
    └── lib/
        └── order_validator.rb
  4. En su función, solicite y utilice los módulos. Debe incluir cada gema de forma individual en el código de la función. No puede utilizar bundler/setup o Bundler.require. Para obtener más información, consulte Utilización de gemas de capas en una función. Ejemplo:

    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

    Puede usar el siguiente evento de prueba para invocar la función:

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

    Respuesta esperada:

    { "statusCode": 200, "body": "{\"message\":\"Order validated successfully\",\"order\":{\"product_id\":\"ABC123\",\"quantity\":2,\"shipping_priority\":\"express\"}}" }

Creación de la capa en Lambda

También puede publicar la capa con la AWS CLI o la consola de Lambda.

AWS CLI

Ejecute el comando publish-layer-version de la AWS CLI para crear la capa de Lambda:

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

El parámetro Tiempos de ejecución compatibles es opcional. Cuando se especifica, Lambda usa este parámetro para filtrar las capas en la consola de Lambda.

Console
Para crear una capa (consola)
  1. Abra la página de Capas de la consola de Lambda.

  2. Elija Crear capa.

  3. Elija Cargar un archivo .zip y, a continuación, cargue el archivo .zip que creó anteriormente.

  4. (Opcional) En Tiempos de ejecución compatibles, elija el tiempo de ejecución de Ruby que corresponda a la versión de Ruby que utilizó para crear la capa.

  5. Seleccione Crear.

Utilización de gemas de capas en una función

En el código de la función, debe especificar de forma explícita cada gema que desee utilizar. Los comandos de Bundler como bundler/setup y Bundler.require no son compatibles. A continuación, se explica cómo utilizar las gemas de una capa en una función de Lambda correctamente:

# 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

Adición de la capa a la función

AWS CLI

Para adjuntar la capa a la función, ejecute el comando update-function-configuration de la AWS CLI. Para el parámetro --layers, use el ARN de la capa. El ARN debe especificar la versión (por ejemplo, arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1). Para obtener más información, consulte Capas y versiones de capas.

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"

La opción cli-binary-format es obligatoria si va a utilizar la versión 2 de la AWS CLI. Para que esta sea la configuración predeterminada, ejecute aws configure set cli-binary-format raw-in-base64-out. Para obtener más información, consulte Opciones de la línea de comandos globales compatibles con AWS CLI en la Guía del usuario de la AWS Command Line Interface versión 2.

Console
Adición de una capa a una función
  1. Abra la página de Funciones en la consola de Lambda.

  2. Elija la función.

  3. Desplácese hacia abajo hasta la sección Capas y, a continuación, elija Agregar una capa.

  4. En Elija una capa, seleccione Capas personalizadas y, a continuación, elija su capa.

    nota

    Si no agregó un tiempo de ejecución compatible al crear la capa, su capa no aparecerá aquí. Puede especificar el ARN de la capa en su lugar.

  5. Elija Agregar.

Aplicación de ejemplo

Para ver más ejemplos de cómo usar las capas de Lambda, consulte la aplicación de ejemplo layer-ruby en el repositorio de GitHub de la Guía para desarrolladores de AWS Lambda. Esta aplicación incluye una capa que contiene la biblioteca tzinfo. Después de crear la capa, puede implementar e invocar las funciones correspondientes para confirmar que la capa funciona como se espera.