建立無伺服器檔案處理應用程式 - AWS Lambda

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

建立無伺服器檔案處理應用程式

Lambda 最常見的使用案例之一是執行檔案處理工作。例如,您可以使用 Lambda 函數從PDF檔案或影像自動建立HTML檔案,或在使用者上傳影像時建立縮圖。

在此範例中,您建立了一個應用程式,該應用程式會在PDF檔案上傳到 Amazon Simple Storage Service (Amazon S3) 貯體時自動加密檔案。要實現此應用程序,請創建以下資源:

  • 供使用者上傳PDF檔案至的 S3 儲存貯體

  • Python 中的 Lambda 函數,用於讀取上傳的文件並創建一個加密的,受密碼保護的版本

  • Lambda 用來儲存加密檔案的第二個 S3 儲存貯體

您也可以建立 AWS Identity and Access Management (IAM) 政策,授與 Lambda 函數在 S3 儲存貯體上執行讀取和寫入操作的權限。

顯示 S3 儲存貯體、Lambda 函數和另一個 S3 儲存貯體之間的資料流程圖
提示

如果您是 Lambda 的新手,建議您建立第一個 Lambda 函數在建立此範例應用程式之前先執行教學課程。

您可以使用 AWS Management Console 或 AWS Command Line Interface (AWS CLI) 建立和設定資源,以手動方式部署應用程式。您也可以使用 AWS Serverless Application Model (AWS SAM) 部署應用程式。 AWS SAM 是一個基礎架構作為代碼(IaC)工具。使用 IaC,您不會手動創建資源,而是在代碼中定義它們,然後自動部署它們。

如果您想在部署此範例應用程式之前,進一步了解如何將 Lambda 與 IaC 搭配使用,請參閱將 Lambda 搭配基礎設施即程式碼 (IaC)

必要條件

在建立範例應用程式之前,請確定已安裝必要的命令列工具。

  • AWS CLI

    您可以使用 AWS Management Console 或手動部署應用程式的資源 AWS CLI。若要使用CLI,請依照《使用AWS Command Line Interface 者指南》中的安裝指示進行安裝。

  • AWS SAM CLI

    如果您想要使用部署範例應用程式 AWS SAM,則必須同時安裝 AWS CLI 和 AWS SAM CLI. 若要安裝 AWS SAM CLI,請遵循使AWS SAM 用者指南中的安裝指

  • 最火焰模塊

    部署應用程序後,您可以使用我們提供的自動化 Python 測試腳本對其進行測試。若要使用此指令碼,請執行下列命令,在本機開發環境中安裝pytest套件:

    pip install pytest

若要使用部署應用程式 AWS SAM,Docker 也必須安裝在您的建置電腦上。

下載範例應用程式檔案

若要建立並測試範例應用程式,請在專案目錄中建立下列檔案:

  • lambda_function.py-執行檔案加密之 Lambda 函數的 Python 函數程式碼

  • requirements.txt-資訊清單檔案,定義 Python 函數程式碼所需的相依性

  • template.yaml-可用於部署應用程序的 AWS SAM 模板

  • test_pdf_encrypt.py-可用於自動測試應用程序的測試腳本

  • pytest.ini-測試腳本的配置文件

展開下列各節以檢視程式碼,並深入瞭解每個檔案在建立和測試應用程式時所扮演的角色。要在本地計算機上創建文件,請複製並粘貼下面的代碼,或從aws-lambda-developer-guide GitHub 存儲庫下載文件。

將以下代碼複製並粘貼到名為的文件中lambda_function.py

from pypdf import PdfReader, PdfWriter import uuid import os from urllib.parse import unquote_plus import boto3 # Create the S3 client to download and upload objects from S3 s3_client = boto3.client('s3') def lambda_handler(event, context): # Iterate over the S3 event object and get the key for all uploaded files for record in event['Records']: bucket = record['s3']['bucket']['name'] key = unquote_plus(record['s3']['object']['key']) # Decode the S3 object key to remove any URL-encoded characters download_path = f'/tmp/{uuid.uuid4()}.pdf' # Create a path in the Lambda tmp directory to save the file to upload_path = f'/tmp/converted-{uuid.uuid4()}.pdf' # Create another path to save the encrypted file to # If the file is a PDF, encrypt it and upload it to the destination S3 bucket if key.lower().endswith('.pdf'): s3_client.download_file(bucket, key, download_path) encrypt_pdf(download_path, upload_path) encrypted_key = add_encrypted_suffix(key) s3_client.upload_file(upload_path, f'{bucket}-encrypted', encrypted_key) # Define the function to encrypt the PDF file with a password def encrypt_pdf(file_path, encrypted_file_path): reader = PdfReader(file_path) writer = PdfWriter() for page in reader.pages: writer.add_page(page) # Add a password to the new PDF writer.encrypt("my-secret-password") # Save the new PDF to a file with open(encrypted_file_path, "wb") as file: writer.write(file) # Define a function to add a suffix to the original filename after encryption def add_encrypted_suffix(original_key): filename, extension = original_key.rsplit('.', 1) return f'{filename}_encrypted.{extension}'
注意

在此範例程式碼中,加密檔案 (my-secret-password) 的密碼會硬式編碼到函數程式碼中。在生產應用程序中,請勿在函數代碼中包含密碼等敏感信息。用 AWS Secrets Manager 於安全地存儲敏感參數。

python 函數代碼包含三個函數-Lambda 在調用函數時運行的處理程序函數,以及兩個名為add_encrypted_suffixencrypt_pdf處理程序調用以執行PDF加密的單獨函數。

當 Amazon S3 叫用您的函數時,Lambda 會將JSON格式化的事件引數傳遞至包含造成呼叫之事件的詳細資料的函數。在此情況下,資訊包括 S3 儲存貯體的名稱以及上傳檔案的物件金鑰。若要進一步了解 Amazon S3 事件物件的格式,請參閱使用 Lambda 處理 Amazon S3 事件通知

然後,您的函數會使用 AWS SDK for Python (Boto3) 將事件物件中指定的PDF檔案下載至其本機暫存儲目錄,然後再使用元件pypdf庫加密這些檔案。

最後,此函數會使用 Boto3 SDK 將加密檔案儲存在 S3 目的地儲存貯體中。

將以下代碼複製並粘貼到名為的文件中requirements.txt

boto3 pypdf

在此範例中,您的函數程式碼只有兩個不屬於標準 Python 程式庫的相依性-SDK 適用於 Python (Boto3),以及函式用來執行加密的pypdfPDF套件。

注意

Python 版本 (Boto3) 包含在 Lambda 執行階段的一部分,因此您的程式碼可以在不將 Boto3 新增至函數的部署套件的情況下執行。SDK但是,為了保持對函數依賴關係的完全控制並避免版本錯位可能出現的問題,Python 的最佳實踐是在函數的部署包中包含所有函數依賴關係。如需進一步了解,請參閱Python 中的執行期相依項

將以下代碼複製並粘貼到名為的文件中template.yaml

AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Resources: EncryptPDFFunction: Type: AWS::Serverless::Function Properties: FunctionName: EncryptPDF Architectures: [x86_64] CodeUri: ./ Handler: lambda_function.lambda_handler Runtime: python3.12 Timeout: 15 MemorySize: 256 LoggingConfig: LogFormat: JSON Policies: - AmazonS3FullAccess Events: S3Event: Type: S3 Properties: Bucket: !Ref PDFSourceBucket Events: s3:ObjectCreated:* PDFSourceBucket: Type: AWS::S3::Bucket Properties: BucketName: EXAMPLE-BUCKET EncryptedPDFBucket: Type: AWS::S3::Bucket Properties: BucketName: EXAMPLE-BUCKET-encrypted

AWS SAM 範本會定義您為應用程式建立的資源。在此範例中,範本使用類型定義 Lambda 函數,並使用該AWS::Serverless::Function類型定義兩個 S3 儲存貯體。AWS::S3::Bucket範本中指定的值區名稱為預留位置。在使用部署應用程式之前 AWS SAM,您需要編輯範本,以使用符合 S3 儲存貯體命名規則的全域唯一名稱重新命名值區。此步驟將在中進一步說明使用部署資源 AWS SAM

Lambda 函數資源的定義會使用S3Event事件屬性來設定函數的觸發程序。每當在源存儲桶中創建對象時,此觸發器都會調用您的函數。

函數定義也會指定要附加至函數執行角色的 AWS Identity and Access Management (IAM) 原則。受AWS 管政策AmazonS3FullAccess為您的函數提供讀取和寫入物件至 Amazon S3 所需的許可。

將以下代碼複製並粘貼到名為的文件中test_pdf_encrypt.py

import boto3 import json import pytest import time import os @pytest.fixture def lambda_client(): return boto3.client('lambda') @pytest.fixture def s3_client(): return boto3.client('s3') @pytest.fixture def logs_client(): return boto3.client('logs') @pytest.fixture(scope='session') def cleanup(): # Create a new S3 client for cleanup s3_client = boto3.client('s3') yield # Cleanup code will be executed after all tests have finished # Delete test.pdf from the source bucket source_bucket = 'EXAMPLE-BUCKET' source_file_key = 'test.pdf' s3_client.delete_object(Bucket=source_bucket, Key=source_file_key) print(f"\nDeleted {source_file_key} from {source_bucket}") # Delete test_encrypted.pdf from the destination bucket destination_bucket = 'EXAMPLE-BUCKET-encrypted' destination_file_key = 'test_encrypted.pdf' s3_client.delete_object(Bucket=destination_bucket, Key=destination_file_key) print(f"Deleted {destination_file_key} from {destination_bucket}") @pytest.mark.order(1) def test_source_bucket_available(s3_client): s3_bucket_name = 'EXAMPLE-BUCKET' file_name = 'test.pdf' file_path = os.path.join(os.path.dirname(__file__), file_name) file_uploaded = False try: s3_client.upload_file(file_path, s3_bucket_name, file_name) file_uploaded = True except: print("Error: couldn't upload file") assert file_uploaded, "Could not upload file to S3 bucket" @pytest.mark.order(2) def test_lambda_invoked(logs_client): # Wait for a few seconds to make sure the logs are available time.sleep(5) # Get the latest log stream for the specified log group log_streams = logs_client.describe_log_streams( logGroupName='/aws/lambda/EncryptPDF', orderBy='LastEventTime', descending=True, limit=1 ) latest_log_stream_name = log_streams['logStreams'][0]['logStreamName'] # Retrieve the log events from the latest log stream log_events = logs_client.get_log_events( logGroupName='/aws/lambda/EncryptPDF', logStreamName=latest_log_stream_name ) success_found = False for event in log_events['events']: message = json.loads(event['message']) status = message.get('record', {}).get('status') if status == 'success': success_found = True break assert success_found, "Lambda function execution did not report 'success' status in logs." @pytest.mark.order(3) def test_encrypted_file_in_bucket(s3_client): # Specify the destination S3 bucket and the expected converted file key destination_bucket = 'EXAMPLE-BUCKET-encrypted' converted_file_key = 'test_encrypted.pdf' try: # Attempt to retrieve the metadata of the converted file from the destination S3 bucket s3_client.head_object(Bucket=destination_bucket, Key=converted_file_key) except s3_client.exceptions.ClientError as e: # If the file is not found, the test will fail pytest.fail(f"Converted file '{converted_file_key}' not found in the destination bucket: {str(e)}") def test_cleanup(cleanup): # This test uses the cleanup fixture and will be executed last pass

自動化測試腳本執行三個測試功能,以確認應用程序的正確操作:

  • 測試會將測試PDF檔案上傳至值區,以test_source_bucket_available確認您的來源值區已成功建立。

  • 該測試會test_lambda_invoked詢問函數的最新 CloudWatch 日誌日誌流,以確認當您上傳測試文件時,Lambda 函數會運行並報告成功。

  • 測試會test_encrypted_file_in_bucket確認您的目的地儲存貯體包含加密test_encrypted.pdf檔案。

執行所有這些測試之後,指令碼會執行額外的清理步驟,以刪除來源test.pdf和目的地值區中的和test_encrypted.pdf檔案。

與 AWS SAM 範本一樣,在此檔案中指定的值區名稱是預留位置。在運行測試之前,您需要使用應用程序的真實存儲桶名稱編輯此文件。此步驟在中進一步說明 使用自動指令碼測試應用程式

將以下代碼複製並粘貼到名為的文件中pytest.ini

[pytest] markers = order: specify test execution order

這是需要指定test_pdf_encrypt.py腳本中的測試運行的順序。

部署應用程式

您可以手動建立和部署此範例應用程式的資源,也可以使用 AWS SAM. 在生產環境中,我們建議您使用 IaC 工具,例如 AWS SAM 快速且重複地部署整個無伺服器應用程式,而無需使用手動程序。

在此範例中,請依照主控台或 AWS CLI 指示操作,了解如何分別設定每個 AWS 資源,或略過以使用部署資源 AWS SAM使用幾個CLI命令快速部署應用程式。

手動部署資源

若要手動部署應用程式,請執行下列步驟:

  • 建立來源和目的地 S3 儲存貯體

  • 建立 Lambda 函數來加密PDF檔案,並將加密版本儲存至 S3 儲存貯體

  • 設定 Lambda 觸發程序,以便在物件上傳至來源儲存貯體時叫用您的函數

請遵循以下段落中的指示來建立和配置資源。

建立兩個 S3 儲存貯體

首先創建兩個 S3 存儲桶。第一個值區是您要將PDF檔案上傳到的來源儲存貯體。當您呼叫函數時,Lambda 會使用第二個儲存貯體來儲存加密的檔案。

Console
若要建立 S3 儲存貯體 (主控台)
  1. 開啟 Amazon S3 主控台的儲存貯體頁面。

  2. 選擇 建立儲存貯體

  3. General configuration (一般組態) 下,執行下列動作:

    1. 請在儲存貯體名稱輸入符合 Amazon S3 儲存貯體命名規則的全域唯一名稱。儲存貯體名稱只能包含小寫字母、數字、句點 (.) 和連字號 (-)。

    2. 對於 AWS 區域,請選擇最接近您地理位置的 AWS 區域。稍後在部署程序中,您必須在其中建立 Lambda 函數 AWS 區域,因此請記下您選擇的區域。

  4. 其他所有選項維持設為預設值,然後選擇建立儲存貯體

  5. 重複步驟 1 到 4 以建立目的地儲存貯體。對於儲存貯體名稱,輸入 SOURCEBUCKET-encrypted,其中 SOURCEBUCKET 是您剛才建立的來源儲存貯體名稱。

AWS CLI
若要建立 S3 儲存貯體 (AWS CLI)
  1. 執行下列CLI命令以建立來源值區。您為儲存貯體選擇的名稱必須是全域唯一的,並遵循 Amazon S3 儲存貯體命名規則。名稱只能包含小寫字母、數字、句點 (.) 和連字號 (-)。對於 regionLocationConstraint,請選擇最接近您地理位置的 AWS 區域

    aws s3api create-bucket --bucket SOURCEBUCKET --region us-west-2 \ --create-bucket-configuration LocationConstraint=us-west-2

    在教學課程稍後,您必須在與來源儲存貯體 AWS 區域 相同的位置建立 Lambda 函數,因此請記下您選擇的區域。

  2. 執行下列命令以建立目的地儲存貯體。對於儲存貯體名稱,必須使用 SOURCEBUCKET-encrypted,其中 SOURCEBUCKET 是您在步驟 1 中建立的來源儲存貯體名稱。對於regionLocationConstraint,請選擇 AWS 區域 您用來建立來源值區的相同項目。

    aws s3api create-bucket --bucket SOURCEBUCKET-encrypted --region us-west-2 \ --create-bucket-configuration LocationConstraint=us-west-2

建立執行角色 (AWS CLI 僅限)

執行角色是授與 Lambda 函數存取 AWS 服務 和資源權限的IAM角色。當您使用 Lambda 主控台建立函數時,Lambda 會自動建立執行角色。如果您選擇使用部署應用程式,則只需手動建立角色 AWS CLI。若要提供 Amazon S3 的函數讀取和寫入存取權,請附加受AWS 管政策AmazonS3FullAccess

Console

只有當您選擇使用部署應用程式時,才需要執行此步驟 AWS CLI。

AWS CLI
建立執行角色並附加AmazonS3FullAccess受管理的原則 (AWS CLI)
  1. 將以下JSON內容儲存在名為的檔案中trust-policy.json。此信任原則允許 Lambda 使用角色的權限,方法是lambda.amazonaws.com授予服務主體呼叫 AWS Security Token Service (AWS STS) AssumeRole 動作的權限。

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
  2. 從您儲存JSON信任原則文件的目錄中,執行下列CLI命令以建立執行角色。

    aws iam create-role --role-name LambdaS3Role --assume-role-policy-document file://trust-policy.json
  3. 若要附加受AmazonS3FullAccess管理的原則,請執行下列CLI命令。

    aws iam attach-role-policy --role-name LambdaS3Role --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess

建立函數部署套件

要建立函數,需建立包含函數程式碼和其相依項的部署套件。對於此應用程序,您的函數代碼使用單獨的庫進行PDF加密。

建立部署套件
  1. 導航到包含您從 GitHub 之前創建或下載的lambda_function.pyrequirements.txt文件的項目目錄,並創建一個名為的新目錄package

  2. 執行下列命令,將requirements.txt檔案中指定的相依性安裝在package目錄中。

    pip install -r requirements.txt --target ./package/
  3. 建立包含應用程式程式碼及其相依性的 .zip 檔案。在 Linux 或 MacOS 中,使用命令列界面執行下列命令。

    cd package zip -r ../lambda_function.zip . cd .. zip lambda_function.zip lambda_function.py

    在 Windows 中,使用您偏好的 zip 工具建立 lambda_function.zip 檔案。確保包含相依項的 lambda_function.py 檔案和資料夾全部都在 .zip 檔案的根目錄中。

您也可以使用 Python 虛擬環境建立部署套件。請參閱使用 .zip 封存檔部署 Python Lambda 函數

建立 Lambda 函式

現在,您可以使用在上一步中建立的部署套件來部署 Lambda 函數。

Console
建立函數的方式 (主控台)

要使用主控台建立 Lambda 函數,首先建立包含一些 ‘Hello world’ 程式碼的基本函數。然後,您可以上傳您在上一個步驟中建立的 the.zip 檔案,以您自己的函數程式碼取代此程式碼。

為了確保您的功能在加密大型PDF檔案時不會逾時,請設定函數的記憶體和逾時設定。您也可以將函數的記錄格式設定為JSON。使用提供的測試腳本時,需要配置JSON格式化日誌,以便從 CloudWatch 日誌中讀取函數的調用狀態以確認成功調用。

  1. 開啟 Lambda 主控台中的函數頁面

  2. 確保您的工作與在其中創 AWS 區域 建 S3 存儲桶的相同。可使用螢幕頂端的下拉式清單來變更區域。

    此圖顯示 Lambda 主控台下拉式區域選單
  3. 選擇建立函數

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

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

    1. 針對 函數名稱 ,請輸入 EncryptPDF

    2. 如果是執行階段,請選擇 Python 3.12

    3. 對於 Architecture (架構),選擇 x86_64

  6. 選擇建立函數

上傳函數程式碼 (主控台)
  1. 程式碼來源窗格中選擇上傳來源

  2. 選擇 .zip 檔案

  3. 選擇上傳

  4. 在檔案選擇器中,選取 .zip 檔案,並選擇開啟

  5. 選擇 Save (儲存)。

若要設定函數記憶體和逾時 (主控台)
  1. 選取函數的「組態」索引標籤。

  2. 在 [一般] 組態窗格中,選擇 [編輯]。

  3. 將「記憶體」設定為 256 MB,將「逾時」設定為 15 秒。

  4. 選擇 Save (儲存)。

若要設定記錄檔格式 (主控台)
  1. 選取函數的「組態」索引標籤。

  2. 選取監視和作業工具

  3. 日誌組態窗格中,選擇編輯

  4. 對於記錄組態,請選取JSON

  5. 選擇 Save (儲存)。

AWS CLI
建立函數 (AWS CLI)
  • 從包含lambda_function.zip檔案的目錄執行下列命令。對於region參數,請以您在其中建立 S3 儲存貯體的區域取代us-west-2

    aws lambda create-function --function-name EncryptPDF \ --zip-file fileb://lambda_function.zip --handler lambda_function.lambda_handler \ --runtime python3.12 --timeout 15 --memory-size 256 \ --role arn:aws:iam::123456789012:role/LambdaS3Role --region us-west-2 \ --logging-config LogFormat=JSON

設定 Amazon S3 觸發器以叫用函數

若要在將檔案上傳到來源儲存貯體時執行 Lambda 函數,您需要設定函數的觸發器。可以使用主控台或 AWS CLI來設定 Amazon S3 觸發條件。

重要

此程序會將 S3 儲存貯體設定為每次在儲存貯體中建立物件時即會調用您的函數。請務必僅在來源儲存貯體上進行設定。如果 Lambda 函數在進行調用的同一個儲存貯體中建立物件,則可以在一個迴圈中連續調用函數。這可能會導致未預期的費用會向您收取 AWS 帳戶.

Console
設定 Amazon S3 觸發條件 (主控台)
  1. 開啟 Lambda 主控台的函數頁面,然後選擇您的函數 (EncryptPDF)。

  2. 選擇 Add trigger (新增觸發條件)

  3. 選取 S3

  4. 儲存貯體下,選取您的來源儲存貯體。

  5. 事件類型下,選取所有物件建立事件

  6. 遞迴叫用下,選取核取方塊,以確認不建議使用相同的 S3 儲存貯體進行輸入和輸出。您可以閱讀無伺服器園地中 導致 Lambda 函數失控的遞迴模式,進一步了解 Lambda 中的遞迴調用模式。

  7. 選擇新增

    當您使用 Lambda 主控台建立觸發條件時,Lambda 會自動建立資源型政策,為您選取的服務授予調用函數的許可。

AWS CLI
設定 Amazon S3 觸發條件 (AWS CLI)
  1. 若要讓 Amazon S3 來源儲存貯體在新增檔案時叫用函數,您首先需要使用資源型政策為函數設定許可。基於資源的政策聲明提供了調用函數的其他 AWS 服務 權限。若要授與 Amazon S3 叫用函數的權限,請執行下列CLI命令。請務必使用您自己的 AWS 帳戶 ID 取代source-account參數,並使用您自己的來源值區名稱。

    aws lambda add-permission --function-name EncryptPDF \ --principal s3.amazonaws.com --statement-id s3invoke --action "lambda:InvokeFunction" \ --source-arn arn:aws:s3:::SOURCEBUCKET \ --source-account 123456789012

    使用此命令定義的政策允許 Amazon S3 僅在來源儲存貯體上發生動作時調用函數。

    注意

    雖然 S3 儲存貯體名稱是全域唯一的,但是在使用以資源為基礎的政策時,最佳做法是指定儲存貯體必須屬於您的帳戶。這是因為如果您刪除值區,則另一個值區可能會 AWS 帳戶 使用相同的 Amazon 資源名稱 (ARN) 建立值區。

  2. 將以下JSON內容儲存在名為的檔案中notification.json。套用至來源值區時,這會JSON設定值區,以便在每次新增物件時傳送通知至 Lambda 函數。將 Lambda 函 AWS 帳戶 ARN數 AWS 區域 中的號碼和號碼取代為您自己的帳戶號碼和區域。

    { "LambdaFunctionConfigurations": [ { "Id": "EncryptPDFEventConfiguration", "LambdaFunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:EncryptPDF", "Events": [ "s3:ObjectCreated:Put" ] } ] }
  3. 執行下列CLI命令,將您建立的JSON檔案中的通知設定套用至來源值區。用您自己的來源儲存貯體名稱取代 SOURCEBUCKET

    aws s3api put-bucket-notification-configuration --bucket SOURCEBUCKET \ --notification-configuration file://notification.json

    若要瞭解有關put-bucket-notification-configuration指令和notification-configuration選項的更多資訊,請參閱《AWS CLI指令參考put-bucket-notification-configuration中的〈〉。

使用部署資源 AWS SAM

若要使用部署範例應用程式 AWS SAM CLI,請執行下列步驟。

確保您已安裝最新版本的,CLI並且 Docker 已安裝在構建計算機上。

  1. 編輯template.yaml檔案以指定 S3 儲存貯體的名稱。S3 儲存貯體必須具有符合 S3 儲存貯體命名規則的全域唯一名稱。

    將值區名稱EXAMPLE-BUCKET取代為您選擇的名稱,其中包含小寫字母、數字、點 (.) 和連字號 (-)。對於目標值區,請取代EXAMPLE-BUCKET-encrypted<source-bucket-name>-encrypted,其中<source-bucket>是您為來源值區選擇的名稱。

  2. 從儲存template.yamllambda_function.pyrequirements.txt檔案的目錄執行下列命令。

    sam build --use-container

    此命令會收集應用程式的建置成品,並將它們放置在適當的格式和位置以進行部署。指定該--use-container選項將在 Lambda 類似的 Docker 容器中構建您的函數。我們在這裡使用它,因此您不需要在本地計算機上安裝 Python 3.12 即可使構建工作。

    在建置程序期間,會在您使用範本中的CodeUri屬性指定的位置 AWS SAM 尋找 Lambda 函數程式碼。在這種情況下,我們指定當前目錄作為 location (./)。

    如果存在requirements.txt檔案, AWS SAM 會使用它來收集指定的相依性。根據預設, AWS SAM 會使用函數程式碼和相依性建立 .zip 部署套件。您也可以選擇使用屬性將函數部署為PackageType容器映像檔。

  3. 若要部署應用程式並建立 AWS SAM 範本中指定的 Lambda 和 Amazon S3 資源,請執行下列命令。

    sam deploy --guided

    使用該--guided標誌意味著 AWS SAM 將顯示提示,以引導您完成部署過程。對於此部署,請按 Enter 接受預設選項。

在部署程序期間, AWS SAM 會在您的中建立下列資源 AWS 帳戶:

  • 一個名為的 AWS CloudFormation 堆棧 sam-app

  • 具有名稱的 Lambda 函數 EncryptPDF

  • 兩個 S3 儲存貯體,其中包含您在編輯template.yaml AWS SAM 範本檔案時選擇的名稱

  • 具有名稱格式的函數的IAM執行角色 sam-app-EncryptPDFFunctionRole-2qGaapHFWOQ8

AWS SAM 完成建立資源後,您應該會看到下列訊息:

Successfully created/updated stack - sam-app in us-west-2

測試應用程式

若要測試應用程式,請將PDF檔案上傳到來源儲存貯體,並確認 Lambda 在目的地儲存貯體中建立檔案的加密版本。在此範例中,您可以使用主控台或使用提供的 AWS CLI測試指令碼手動測試此測試。

對於生產應用程式,您可以使用傳統的測試方法和技術 (例如單元測試) 來確認 Lambda 函數程式碼的正常運作。最佳做法也是在提供的測試腳本中進行測試,這些測試腳本使用真實的基於雲的資源進行集成測試。雲端中的整合測試可確認您的基礎結構已正確部署,且事件會如預期般在不同服務之間流動。如需進一步了解,請參閱 如何測試無伺服器功能和應用程式

手動測試應用程式

您可以將PDF檔案新增至 Amazon S3 來源儲存貯體,以手動測試函數。將檔案新增至來源儲存貯體時,應自動叫用 Lambda 函數,並將檔案的加密版本儲存在目標儲存貯體中。

Console
透過上傳檔案 (主控台) 測試您的應用程式
  1. 若要將PDF檔案上傳到 S3 儲存貯體,請執行下列動作:

    1. 開啟 Amazon S3 主控台的儲存貯體頁面,並選擇來源儲存貯體。

    2. 選擇上傳

    3. 選擇「新增檔案」,然後使用檔案選擇器選擇您要上傳的PDF檔案。

    4. 選擇開啟,然後選擇上傳

  2. 請執行下列動作,確認 Lambda 已將PDF檔案的加密版本儲存在目標儲存貯體中:

    1. 導覽回 Amazon S3 主控台的儲存貯體頁面,然後選擇目的地儲存貯體。

    2. 在 [物件] 窗格中,您現在應該會看到具有名稱格式的檔案 filename_encrypted.pdf (其中filename.pdf是您上傳至來源值區的檔案名稱)。若要下載加密檔案PDF,請選取檔案,然後選擇「下載」。

    3. 確認您可以使用 Lambda 函數使用密碼開啟下載的檔案 (my-secret-password)。

AWS CLI
若要透過上傳檔案來測試您的應用程式 (AWS CLI)
  1. 從包含您要上傳的PDF檔案的目錄中,執行下列CLI命令。將 --bucket 參數取代為來源儲存貯體名稱。對於--key--body參數,請使用測試檔案的檔案名稱。

    aws s3api put-object --bucket SOURCEBUCKET --key test.pdf --body ./test.pdf
  2. 確認您的函數已建立檔案的加密版本,並將其儲存到目標 S3 儲存貯體。執行下列CLI命令,並以您自己的目標值區的名稱取代SOURCEBUCKET-encrypted

    aws s3api list-objects-v2 --bucket SOURCEBUCKET-encrypted

    如果函數成功運作,則您會看到類似以下內容的輸出。您的目標值區應包含名稱格式的檔案<your_test_file>_encrypted.pdf,其中<your_test_file>是您上傳的檔案名稱。

    { "Contents": [ { "Key": "test_encrypted.pdf", "LastModified": "2023-06-07T00:15:50+00:00", "ETag": "\"7781a43e765a8301713f533d70968a1e\"", "Size": 2763, "StorageClass": "STANDARD" } ] }
  3. 若要下載 Lambda 儲存在目的地儲存貯體中的檔案,請執行下列CLI命令。將--bucket參數取代為目的地值區的名稱。對於--key參數,請使用文件名<your_test_file>_encrypted.pdf,其中<your_test_file>是您上傳的測試文件的名稱。

    aws s3api get-object --bucket SOURCEBUCKET-encrypted --key test_encrypted.pdf my_encrypted_file.pdf

    此指令會將檔案下載到您目前的目錄,並將其儲存為my_encrypted_file.pdf

  4. 確認您可以使用 Lambda 函數使用(my-secret-password)保護它的密碼打開下載的文件。

使用自動指令碼測試應用程式

要使用提供的測試腳本測試您的應用程序,請首先確保該pytest模塊已安裝在本地環境中。您可以執pytest行下列命令來進行安裝:

pip install pytest

您也需要編輯test_pdf_encrypt.py檔案中的程式碼,以 Amazon S3 來源和目的地儲存貯體的名稱取代預留位置儲存貯體名稱。對 test_pdf_encrypt.py 進行下列變更:

  • test_source_bucket_available函數中,EXAMPLE-BUCKET替換為源存儲桶的名稱。

  • test_encrypted_file_in_bucket函數中,EXAMPLE-BUCKET-encrypted替換為<source-bucket>-encrypted,其中<source-bucket>是源存儲桶的名稱。

  • cleanup函數中,EXAMPLE-BUCKET替換為源存儲桶的名稱,並替換EXAMPLE-BUCKET-encrypted≪source-bucket>-encrypted,其中<source-bucket>是源存儲桶的名稱。

要運行測試,請執行以下操作:

  • 在包含test_pdf_encrypt.py和PDF檔案的目錄test.pdf中儲存一個名為的pytest.ini檔案。

  • 打開終端機或 shell 程序,並從包含測試文件的目錄運行以下命令。

    pytest -s -v

測試完成後,您應該會看到如下所示的輸出:

============================================================== test session starts ========================================================= platform linux -- Python 3.12.2, pytest-7.2.2, pluggy-1.0.0 -- /usr/bin/python3 cachedir: .pytest_cache hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/home/pdf_encrypt_app/.hypothesis/examples') Test order randomisation NOT enabled. Enable with --random-order or --random-order-bucket=<bucket_type> rootdir: /home/pdf_encrypt_app, configfile: pytest.ini plugins: anyio-3.7.1, hypothesis-6.70.0, localserver-0.7.1, random-order-1.1.0 collected 4 items test_pdf_encrypt.py::test_source_bucket_available PASSED test_pdf_encrypt.py::test_lambda_invoked PASSED test_pdf_encrypt.py::test_encrypted_file_in_bucket PASSED test_pdf_encrypt.py::test_cleanup PASSED Deleted test.pdf from EXAMPLE-BUCKET Deleted test_encrypted.pdf from EXAMPLE-BUCKET-encrypted =============================================================== 4 passed in 7.32s ==========================================================

後續步驟

現在,您已經創建了這個示例應用程序,您可以使用提供的代碼作為基礎來創建其他類型的文件處理應用程序。修改lambda_function.py檔案中的程式碼,以針對您的使用案例實作檔案處理邏輯。

許多典型的檔案處理使用案例都涉及影像處理。使用 Python 時,最流行的圖像處理庫(如枕頭)通常包含 C 或 C ++ 組件。為了確保函數的部署套件與 Lambda 執行環境相容,請務必使用正確的來源分發二進位檔。

使用部署資源時 AWS SAM,您需要採取一些額外的步驟,在部署套件中包含正確的來源散發。因為 AWS SAM 不會針對與建置機器不同的平台安裝相依性,因此如果您的建置機器使用的作業系統或架構與 Lambda 執行環境不同,則在requirements.txt檔案中指定正確的來源散發 (.whl檔案) 將無法運作。相反,您應該執行以下操作之一:

  • 運行時使用該--use-container選項sam build。當您指定此選項時,會 AWS SAM 下載與 Lambda 執行環境相容的容器基礎映像,並使用該映像在 Docker 容器中建立函數的部署套件。若要深入了解,請參閱在提供的容器內建置 Lambda 函數

  • 使用正確的來源散發二進位檔自行建置函式的 .zip 部署套件,並將 .zip 檔案儲存在範本中指定的目錄CodeUri中 AWS SAM 。若要進一步瞭解如何使用二進位發行版為 Python 建置 .zip 部署套件,請參閱建立含相依項的 .zip 部署套件建立含原生程式庫的 .zip 部署套件