針對 Ruby Lambda 函數使用層 - AWS Lambda

針對 Ruby Lambda 函數使用層

使用 Lambda 層封裝要在多個函式之間重複使用的程式碼與相依項。層通常具備程式庫相依性、自訂執行期或組態檔案。建立層包含三個一般步驟:

  1. 封裝層內容。這表示建立 .zip 封存檔,其中包含您要在函數中使用的相依項。

  2. 在 Lambda 中建立層。

  3. 將層新增至函數中。

封裝層內容

若要建立層,請將套件封裝成符合以下要求的 .zip 壓縮檔:

  • 使用計劃用於 Lambda 函式的相同 Ruby 版本來建立層。例如,若針對 Ruby 3.4 建立層,需為函式使用 Ruby 3.4 執行時期。

  • 層的 .zip 檔案必須使用下列任一目錄結構:

    • ruby/gems/x.x.x (其中 x.x.x 表示 Ruby 版本,例如 3.4.0)

    • ruby/lib

    如需更多詳細資訊,請參閱 每個 Lambda 執行時間的層路徑

  • 層中的套件必須與 Linux 相容。Lambda 函式會在 Amazon Linux 上執行。

您可以建立包含第三方 Ruby gem 或您自訂 Ruby 模組與類別的層。許多熱門的 Ruby gem 都包含必須針對 Lambda Linux 環境編譯的原生延伸模組 (C 程式碼)。

純 Ruby gem 僅包含 Ruby 程式碼,不需要編譯。這些 gem 更易於封裝,可在不同平台上運作。

使用純 Ruby gem 建立層
  1. 建立 Gemfile,指定要包含在層中的純 Ruby gem:

    範例 Gemfile
    source 'https://rubygems.org' gem 'tzinfo'
  2. 使用封裝程式將 gem 安裝至 vendor/bundle 目錄:

    bundle config set --local path vendor/bundle bundle install
  3. 將已安裝的 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/
  4. 壓縮層內容:

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

    .zip 檔案的目錄結構應如下所示:

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

    必須在函式程式碼中個別要求每個 gem。不能使用 bundler/setupBundler.require。如需更多詳細資訊,請參閱 在函式中使用來自層的 gem

許多熱門的 Ruby gem 都包含必須針對目標平台編譯的原生延伸模組 (C 程式碼)。帶有原生延伸模組的熱門 gem 包括 nokogiripgmysql2sqlite3ffi。這些 gem 必須在與 Lambda 執行時期相容的 Linux 環境中建置。

使用帶有原生延伸模組的 gem 建立層
  1. 建立 Gemfile

    範例 Gemfile
    source 'https://rubygems.org' gem 'nokogiri' gem 'httparty'
  2. 使用 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/
  3. 建置映像並擷取層:

    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。不能使用 bundler/setupBundler.require。如需更多詳細資訊,請參閱 在函式中使用來自層的 gem

使用自訂的程式碼建立層
  1. 建立層所需的目錄結構:

    mkdir -p ruby/lib
  2. 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
  3. 壓縮層內容:

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

    .zip 檔案的目錄結構應如下所示:

    ruby/              
    └── lib/
        └── order_validator.rb
  4. 在函式中,要求並使用這些模組。必須在函式程式碼中個別要求每個 gem。不能使用 bundler/setupBundler.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 主控台來發布層。

AWS CLI

執行 publish-layer-version AWS CLI 命令來建立 Lambda 層:

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

相容的執行時期參數為選用參數。指定此參數後,Lambda 會據此在 Lambda 主控台中篩選層。

Console
建立圖層 (主控台)
  1. 開啟 Lambda 主控台中的 層頁面

  2. 選擇 建立圖層

  3. 選擇上傳 .zip 檔案,然後上傳先前建立的 .zip 壓縮檔。

  4. (選用) 在相容的執行時期欄位中,選擇與用於建置層的 Ruby 版本相對應的 Ruby 執行時期。

  5. 選擇建立

在函式中使用來自層的 gem

在函式程式碼中,必須明確要求要使用的每個 gem。不支援 bundler/setupBundler.require 等封裝程式命令。以下是在 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

將層新增至函式

AWS CLI

若要將層連接至函式,請執行 update-function-configuration AWS CLI 命令。對於 --layers 參數,請使用層 ARN。ARN 必須指定版本 (例如 arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1)。如需更多詳細資訊,請參閱 層和層的版本

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"

如果您使用 AWS CLI 第 2 版,則需要 cli-binary-format 選項。若要讓此成為預設的設定,請執行 aws configure set cli-binary-format raw-in-base64-out。若要取得更多資訊,請參閱《AWS Command Line Interface 使用者指南第 2 版》AWS CLI 支援的全域命令列選項

Console
將層新增至函式
  1. 開啟 Lambda 主控台中的函數頁面

  2. 選擇函式。

  3. 向下捲動至區段,然後選擇新增層

  4. 選擇層欄位中,選取自訂層,然後選擇要使用的層。

    注意

    如果未在建立層時新增相容的執行時期,此處不會列出層。您可以改為指定層 ARN。

  5. 選擇新增

應用程式範例

如需如何使用 Lambda 層的更多範例,請參閱 AWS Lambda Developer Guide GitHub repository 中的 layer-ruby 範例應用程式。此應用程式包含一個內含 tzinfo 程式庫的層。建立層之後,您可以部署並調用相應的函式,驗證層是否如預期那樣運作。