使用 Ruby Lambda 函數的 .zip 封存檔 - AWS Lambda

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用 Ruby Lambda 函數的 .zip 封存檔

AWS Lambda 函數的代碼包含一個包含函數處理程序代碼的 .rb 文件,以及代碼所依賴的任何其他依賴項(gem)。若要將此函數程式碼部署到 Lambda,您可以使用部署套件。此套件可以是 .zip 封存檔或容器映像。如需搭配 Ruby 使用容器映像的詳細資訊,請參閱使用容器映像部署 Ruby Lambda 函數

若要建立 .zip 封存檔的部署套件,您可以使用命令列工具的內建 .zip 封存檔公用程式,或任何其他 .zip 檔案公用程式 (例如 7zip)。以下各節顯示的範例假設您在 Linux 或 MacOS 環境中使用命令列 zip 工具。若要在 Windows 中使用相同命令,您可以安裝適用於 Linux 的 Windows 子系統,以取得 Ubuntu 和 Bash 的 Windows 整合版本。

請注意,Lambda 使用 POSIX 檔案許可,因此在建立 .zip 封存檔之前,您可能需要設定部署套件資料夾的許可

以下各節中的範例命令使用 Bundler 公用程式,將相依項新增至部署套件。若要安裝 bundler,請執行下列命令。

gem install bundler

Ruby 中的相依項

對於使用 Ruby 執行期的 Lambda 函數,相依項可以是任何 Ruby gem。使用 .zip 封存部署函數時,您可以使用函數程式碼將這些相依項新增至 .zip 檔案,或使用 Lambda 層。 圖層是單獨的 .zip 檔案,可以包含其他程式碼和內容。若要進一步了解如何使用 Lambda 層,請參閱 使用 Lambda 層

紅寶石執行階段包含 AWS SDK for Ruby. 如果函數使用 SDK,則不需要將其與程式碼綁定在一起。但是,若要維持相依項的完全控制或使用特定版本的 SDK,可以將其新增到函數的部署套件。您可以將 SDK 包含在 .zip 檔案中,也可以使用 Lambda 層進行新增。.zip 檔案或 Lambda 層中的相依項優先於執行期中包含的版本。要了解您的運行時版本中包含了哪個版本的 SDK for Ruby,請參閱包含執行階段的 SDK 版本

在 AWS  共同責任模式下,您負責管理函數部署套件中的任何相依項。這包括套用更新和安全性修補程式。若要更新函數部署套件中的相依項,請先建立新的 .zip 檔案,然後將其上傳至 Lambda。如需詳細資訊,請參閱 建立含相依項的 .zip 部署套件使用 .zip 檔案建立及更新 Ruby Lambda 函數

建立不含相依項的 .zip 部署套件

如果您的函數程式碼沒有相依項,則 .zip 檔案只會包含具有函數處理常式程式碼的 .rb 檔案。使用您慣用的 zip 公用程式建立 .zip 檔案,並將 .rb 檔案放在根目錄下。如果 .rb 檔案不在 .zip 檔案的根目錄下,則 Lambda 將無法執行您的程式碼。

若要了解如何部署 .zip 檔案以建立新的 Lambda 函數或更新現有函數,請參閱使用 .zip 檔案建立及更新 Ruby Lambda 函數

建立含相依項的 .zip 部署套件

如果您的函數程式碼相依於其他 Ruby gem,則您可以使用函數程式碼將這些相依項新增至 .zip 檔案,或使用 Lambda 層。本節中的指示說明如何在 .zip 部署套件中包含相依項。如需如何在層中包含相依項的指示,請參閱為相依項建立 Ruby 層

假設函數程式碼儲存在專案目錄中名為 lambda_function.rb 的檔案中。下列範例 CLI 命令會建立名為 my_deployment_package.zip 的 .zip 檔案,其中包含函數程式碼及其相依項。

建立部署套件
  1. 在專案目錄中,建立 Gemfile 以在其中指定相依項。

    bundle init
  2. 使用您偏好的文字編輯器,編輯 Gemfile 以指定函數的相依項。例如,若要使用 TZInfo gem,請編輯 Gemfile,如下所示。

    source "https://rubygems.org" gem "tzinfo"
  3. 執行以下命令來安裝專案目錄中 Gemfile 指定的 gem。此命令將 vendor/bundle 設定為 gem 安裝的預設路徑。

    bundle config set --local path 'vendor/bundle' && bundle install

    您應該會看到類似下列的輸出。

    Fetching gem metadata from https://rubygems.org/........... Resolving dependencies... Using bundler 2.4.13 Fetching tzinfo 2.0.6 Installing tzinfo 2.0.6 ...
    注意

    若稍後再次在全域安裝 gem,請執行下列命令。

    bundle config set --local system 'true'
  4. 建立 .zip 封存檔,其中包含具有函數處理常式程式碼的 lambda_function.rb 檔案以及在上一個步驟中安裝的相依項。

    zip -r my_deployment_package.zip lambda_function.rb vendor

    您應該會看到類似下列的輸出。

    adding: lambda_function.rb (deflated 37%) adding: vendor/ (stored 0%) adding: vendor/bundle/ (stored 0%) adding: vendor/bundle/ruby/ (stored 0%) adding: vendor/bundle/ruby/3.2.0/ (stored 0%) adding: vendor/bundle/ruby/3.2.0/build_info/ (stored 0%) adding: vendor/bundle/ruby/3.2.0/cache/ (stored 0%) adding: vendor/bundle/ruby/3.2.0/cache/aws-eventstream-1.0.1.gem (deflated 36%) ...

為相依項建立 Ruby 層

本節中的指示說明如何在層中包含相依項。如需如何在部署套件中包含相依項的指示,請參閱建立含相依項的 .zip 部署套件

將層新增至函數時,Lambda 會將層內容載入該執行環境的 /opt 目錄。在每一次 Lambda 執行期中,PATH 變數已包含 /opt 目錄中的特定資料夾路徑。若要確保PATH變數會擷取圖層內容,您的圖層 .zip 檔案應該在下列資料夾路徑中具有其相依性:

  • ruby/gems/2.7.0 (GEM_PATH)

  • ruby/lib (RUBYLIB)

例如,您的層 .zip 檔案結構可能如下所示:

json.zip └ ruby/gems/2.7.0/ | build_info | cache | doc | extensions | gems | └ json-2.1.0 └ specifications └ json-2.1.0.gemspec

此外,Lambda 會自動偵測 /opt/lib 目錄中的程式庫,以及 /opt/bin 目錄中的二進位檔案。若要確保 Lambda 正確找到您的層內容,您也可以建立結構如下的層:

custom-layer.zip └ lib | lib_1 | lib_2 └ bin | bin_1 | bin_2

封裝層之後,請參閱在 Lambda 中建立和刪除層為函數新增層,完成層設定。

建立含原生程式庫的 .zip 部署套件

諸如 nokogirinio4rmysql 等許多常見 Ruby gem 包含用 C 語言編寫的原生延伸模組。將包含 C 程式碼的程式庫新增至部署套件時,必須正確建置套件,以確保其與 Lambda 執行環境相容。

對於生產應用程式,我們建議您使用 AWS Serverless Application Model (AWS SAM) 來建置和部署您的程式碼。在 AWS SAM 使用該sam build --use-container選項在 Lambda 類似的 Docker 容器中構建函數。若要進一步了解如 AWS SAM 何使用部署函數程式碼,請參閱AWS SAM 開發人員指南中的建置應用程式。

若要建立包含含有原生擴充功能之 gem 的 .zip 部署套件 AWS SAM,您也可以使用容器將相依性封裝在與 Lambda Ruby 執行階段環境相同的環境中。若要完成這些步驟,必須在建置電腦上安裝 Docker。若要進一步了解如何安裝 Docker,請參閱 Install Docker Engine

在 Docker 容器中建立 .zip 部署套件
  1. 在本機建置電腦上建立一個資料夾,將容器儲存在其中。在該資料夾中,建立一個名為 dockerfile 的檔案並將以下程式碼貼到其中。

    FROM public.ecr.aws/sam/build-ruby3.2:latest-x86_64 RUN gem update bundler CMD "/bin/bash"
  2. 在建立 dockerfile 的資料夾中,執行以下命令以建立 Docker 容器。

    docker build -t awsruby32 .
  3. 導覽到包含 .rb 檔案 (具有函數處理常式程式碼) 和 Gemfile (用於指定函數相依項) 的專案目錄。從該目錄內,執行下列命令以啟動 Lambda Ruby 容器。

    Linux/MacOS
    docker run --rm -it -v $PWD:/var/task -w /var/task awsruby32
    注意

    在 MacOS 中,您可能會看到警告,通知您所請求映像的平台與偵測到的主機平台不符。請忽略此警告。

    Windows PowerShell
    docker run --rm -it -v ${pwd}:var/task -w /var/task awsruby32

    當容器啟動時,應能看到一個 bash 提示。

    bash-4.2#
  4. 設定套件公用程式,以安裝本機 vendor/bundle 目錄中 Gemfile 指定的 gem,並安裝相依項。

    bash-4.2# bundle config set --local path 'vendor/bundle' && bundle install
  5. 使用函數程式碼和其相依項建立 .zip 部署套件。在此範例中,包含函數處理常式程式碼的檔案命名為 lambda_function.rb

    bash-4.2# zip -r my_deployment_package.zip lambda_function.rb vendor
  6. 結束容器並回到本機專案目錄。

    bash-4.2# exit

    現在可以使用 .zip 檔案部署套件來建立或更新 Lambda 函數。請參閱使用 .zip 檔案建立及更新 Ruby Lambda 函數

使用 .zip 檔案建立及更新 Ruby Lambda 函數

建立 .zip 部署套件後,您可以使用該套件建立新的 Lambda 函數或更新現有函數。您可以使用 Lambda 主控台、和 Lambda API 來部署您的 .zip 套件。 AWS Command Line Interface您也可以使用 AWS Serverless Application Model  (AWS SAM) 和  AWS CloudFormation 建立並更新 Lambda 函數。

Lambda 的 .zip 部署套件大小上限為 250 MB (解壓縮)。請注意,此限制適用於您上傳的所有檔案 (包括任何 Lambda 層) 的大小總和。

Lambda 執行時間需有許可才能讀取部署套裝服務中的檔案。在 Linux 權限八進制標記法中,Lambda 需要 644 個權限才能用於不可執行的檔案 (rw-r--r--) 和 755 個權限 () 用於目錄和可執行檔。rwxr-xr-x

在 Linux 和 MacOS 中,使用 chmod 命令變更部署套件中檔案和目錄的檔案許可。例如,若要提供可執行檔正確的許可,請執行下列命令。

chmod 755 <filepath>

若要在 Windows 中變更檔案許可,請參閱 Microsoft Windows 文件的 Set, View, Change, or Remove Permissions on an Object

透過主控台使用 .zip 檔案建立及更新函數

若要建立新函數,您必須先在主控台中建立函數,然後上傳您的 .zip 封存檔。若要更新現有函數,請開啟函數的頁面,然後按照同樣的程序新增更新後的 .zip 檔案。

如果您的 .zip 檔案小於 50 MB,您可以透過直接從本機電腦上傳檔案來建立或更新函數。若 .zip 檔案大於 50 MB,您必須先將套件上傳至 Amazon S3 儲存貯體。如需有關如何使用將檔案上傳到 Amazon S3 儲存貯體的指示 AWS Management Console,請參閱開始使用 Amazon S3。若要使用上載檔案 AWS CLI,請參閱《使用指南》中的AWS CLI 〈移動物件

注意

您無法變更現有函數的部署套件類型 (.zip 或容器映像檔)。例如,您無法將容器映像函數轉換為使用 .zip 檔案封存。您必須建立新的函數。

若要建立新的函數 (主控台)
  1. 開啟 Lambda 主控台的函數頁面,然後選擇建立函數

  2. 選擇 Author from scratch (從頭開始撰寫)。

  3. 基本資訊下,請執行下列動作:

    1. 函數名稱中輸入函數名稱。

    2. 執行期中選取要使用的執行期。

    3. (選用) 在架構中選擇要用於函數的指令集架構。預設架構值為 x86_64。請確定函數的 .zip 部署套件與您選取的指令集架構相容。

  4. (選用) 在 許可 下,展開 變更預設執行角色 。您可建立新的執行角色,或使用現有的角色。

  5. 選擇建立函數。Lambda 會使用您選擇的執行期建立一個基本的「Hello world」函數。

若要從本機電腦上傳 .zip 封存檔 (主控台)
  1. 在 Lambda 主控台的函數頁面中選擇要上傳 .zip 檔案的函數。

  2. 選取程式碼索引標籤。

  3. 程式碼來源窗格中選擇上傳來源

  4. 選擇 .zip 檔案

  5. 若要上傳 .zip 檔案,請執行下列操作:

    1. 選擇上傳,然後在檔案選擇器中選取您的 .zip 檔案。

    2. 選擇 Open (開啟)。

    3. 選擇儲存

若要從 Amazon S3 儲存貯體上傳 .zip 封存檔 (控制台)
  1. 在 Lambda 主控台的函數頁面中選擇要上傳新 .zip 檔案的函數。

  2. 選取程式碼索引標籤。

  3. 程式碼來源窗格中選擇上傳來源

  4. 選擇 Amazon S3 位置

  5. 貼上 .zip 檔案的 Amazon S3 連結 URL,然後選擇儲存

使用主控台程式碼編輯器更新 .zip 檔案函數

對於某些具有 .zip 部署套件的函數,您可以使用 Lambda 主控台的內建程式碼編輯器直接更新函數程式碼。若要使用此功能,您的函數必須符合下列條件:

  • 您的函數必須使用其中一種轉譯語言執行期 (Python、Node.js 或 Ruby)

  • 函數的部署套件必須小於 3MB。

具有容器映像部署套件之函數的函數程式碼無法直接在主控台中編輯。

若要使用主控台程式碼編輯器更新函數程式碼
  1. 開啟 Lambda 主控台的函數頁面,然後選取您的函數。

  2. 選取程式碼索引標籤。

  3. 程式碼來源窗格中,選取您的原始程式碼檔案,然後在整合式程式碼編輯器中加以編輯。

  4. 完成編輯程式碼後,請選擇部署,以儲存變更並更新函數。

使用 .zip 檔案建立和更新函數 AWS CLI

您可以使用 AWS CLI 建立新函數,或使用 .zip 檔案更新現有函數。使用建立函數update-function-code命令來部署您的 .zip 套件。如果您的 .zip 檔案小於 50 MB,則可以從本機建置電腦的檔案位置上傳 .zip 套件。若檔案較大,則必須先從 Amazon S3 儲存貯體上傳 .zip 套件。如需有關如何使用將檔案上傳到 Amazon S3 儲存貯體的指示 AWS CLI,請參閱使用AWS CLI 者指南中的移動物件

注意

如果您使用從 Amazon S3 儲存貯體上傳 .zip 檔案 AWS CLI,則該儲存貯體必須與您的函數位於 AWS 區域 相同的位置。

若要使用 .zip 檔案與建立新函數 AWS CLI,您必須指定下列項目:

  • 函數名稱 (--function-name)

  • 函數的執行期 (--runtime)

  • 函數執行角色的 Amazon Resource Name (ARN) (--role)

  • 函數程式碼中處理常式方法的名稱 (--handler)

您也必須指定 .zip 檔案的位置。如果您的 .zip 檔案位於本機建置電腦上的資料夾中,請使用 --zip-file 選項來指定檔案路徑,如下列範例命令所示。

aws lambda create-function --function-name myFunction \ --runtime ruby3.2 --handler lambda_function.lambda_handler \ --role arn:aws:iam::111122223333:role/service-role/my-lambda-role \ --zip-file fileb://myFunction.zip

若要在 Amazon S3 儲存貯體中指定 .zip 檔案的位置,請使用如下列範例命令所示的 --code 選項。您只需針對版本控制的物件使用 S3ObjectVersion 參數。

aws lambda create-function --function-name myFunction \ --runtime ruby3.2 --handler lambda_function.lambda_handler \ --role arn:aws:iam::111122223333:role/service-role/my-lambda-role \ --code S3Bucket=myBucketName,S3Key=myFileName.zip,S3ObjectVersion=myObjectVersion

若要使用 CLI 更新現有函數,您可以使用 --function-name 參數指定函數的名稱。您也必須指定要用來更新函數程式碼的 .zip 檔案的位置。如果您的 .zip 檔案位於本機建置電腦上的資料夾中,請使用 --zip-file 選項來指定檔案路徑,如下列範例命令所示。

aws lambda update-function-code --function-name myFunction \ --zip-file fileb://myFunction.zip

若要在 Amazon S3 儲存貯體中指定 .zip 檔案的位置,請使用如下列範例命令所示的 --s3-bucket 和 --s3-key 選項。您只需針對版本控制的物件使用 --s3-object-version 參數。

aws lambda update-function-code --function-name myFunction \ --s3-bucket myBucketName --s3-key myFileName.zip --s3-object-version myObject Version

透過 Lambda API 使用 .zip 檔案建立及更新函數

若要使用 .zip 封存檔建立及更新函數,請使用下列 API 操作:

使用 .zip 文件創建和更新函數 AWS SAM

AWS Serverless Application Model (AWS SAM) 是一個工具組,可協助簡化在 AWS上建置和執行無伺服器應用程式的程序。您可以在 YAML 或 JSON 範本中定義應用程式的資源,並使用 AWS SAM 命令列介面 (AWS SAM CLI) 來建置、封裝及部署應用程式。當您從 AWS SAM 範本建立 Lambda 函數時, AWS SAM 會使用函數程式碼和您指定的任何相依性,自動建立 .zip 部署套件或容器映像檔。若要進一步了解如 AWS SAM 何使用建置和部署 Lambda 函數,請參閱開AWS Serverless Application Model發人員指南 AWS SAM中的入門使用。

您也可以使用現有的 .zip 檔案封存 AWS SAM 來建立 Lambda 函數。若要使用建立 Lambda 函數 AWS SAM,您可以將 .zip 檔案儲存在 Amazon S3 儲存貯體或建置機器的本機資料夾中。如需有關如何使用將檔案上傳到 Amazon S3 儲存貯體的指示 AWS CLI,請參閱使用AWS CLI 者指南中的移動物件

在 AWS SAM 範本中,AWS::Serverless::Function資源會指定您的 Lambda 函數。在本資源中設定下列屬性,以使用 .zip 封存檔建立函數:

  • PackageType:設定為 Zip

  • CodeUri-設定為函數程式碼的 Amazon S3 URI、本機資料夾的路徑或FunctionCode物件

  • Runtime:設定為所選執行期

使用時 AWS SAM,如果您的 .zip 檔案大於 50MB,則不需要先將其上傳到 Amazon S3 儲存貯體。 AWS SAM 可以從本地構建機器上的位置上傳 .zip 軟件包,最大允許大小為 250MB(解壓縮)。

若要進一步瞭解如何使用 .zip 檔案部署函數 AWS SAM,請參閱AWS SAM 開發人員指南AWS::Serverless::Function中的。

使用 .zip 文件創建和更新函數 AWS CloudFormation

您可以使 AWS CloudFormation 用 .zip 檔案封存來建立 Lambda 函數。若要使用 .zip 檔案建立 Lambda 函數,您必須先將檔案上傳至 Amazon S3 儲存貯體。如需有關如何使用將檔案上傳到 Amazon S3 儲存貯體的指示 AWS CLI,請參閱使用AWS CLI 者指南中的移動物件

在 AWS CloudFormation 範本中,AWS::Lambda::Function資源會指定您的 Lambda 函數。在本資源中設定下列屬性,以使用 .zip 封存檔建立函數:

  • PackageType:設定為 Zip

  • Code:在 S3Bucket 和 S3Key 欄位中輸入 Amazon S3 儲存貯體名稱和 .zip 檔案名稱。

  • Runtime:設定為所選執行期

AWS CloudFormation 產生的 .zip 檔案不能超過 4MB。若要進一步瞭解有關使用 .zip 檔案部署函數的更多資訊 AWS CloudFormation,請參閱使用AWS CloudFormation 者指南AWS::Lambda::Function中的。