Erstellen Sie eine Serverless-Dateiverarbeitungs-App - AWS Lambda

Erstellen Sie eine Serverless-Dateiverarbeitungs-App

Einer der häufigsten Anwendungsfälle für Lambda ist die Ausführung von Dateiverarbeitungsaufgaben. Sie können beispielsweise eine Lambda-Funktion verwenden, um automatisch PDF-Dateien aus HTML-Dateien oder Bildern zu erstellen oder um Miniaturansichten zu erstellen, wenn ein Benutzer ein Bild hochlädt.

In diesem Beispiel erstellen Sie eine App, die PDF-Dateien automatisch verschlüsselt, wenn sie in einen Amazon Simple Storage Service (Amazon S3)-Bucket uploaden. Um diese Anwendung zu implementieren, erstellen Sie die folgenden Ressourcen:

  • Ein S3-Bucket, in das Benutzer PDF-Dateien hochladen können

  • Eine Lambda-Funktion in Python, die die hochgeladene Datei liest und eine verschlüsselte, passwortgeschützte Version davon erstellt

  • Ein zweiter S3-Bucket für Lambda zum Speichern der verschlüsselten Datei

Sie erstellen auch eine AWS Identity and Access Management (IAM)-Richtlinie, um Ihrer Lambda-Funktion die Berechtigung zum Ausführen von Lese- und Schreibvorgängen in Ihren S3-Buckets zu erteilen.

Diagramm: Datenfluss zwischen einem S3-Bucket, einer Lambda-Funktion und einem anderen S3-Bucket
Tipp

Wenn Sie ganz neu bei Lambda sind, empfehlen wir Ihnen, vor der Erstellung dieser Beispiel-App mit dem Tutorial Erstellen Sie Ihre erste Lambda-Funktion zu beginnen.

Sie können Ihre App manuell bereitstellen, indem Sie Ressourcen mit dem AWS-Managementkonsole oder dem AWS Command Line Interface (AWS CLI) erstellen und konfigurieren. Sie können die App auch mithilfe von AWS Serverless Application Model (AWS SAM) bereitstellen. AWS SAM ist ein Infrastructure as Code (IaC)-Tool. Mit IaC erstellen Sie Ressourcen nicht manuell, sondern definieren sie im Code und stellen sie dann automatisch bereit.

Wenn Sie mehr über die Verwendung von Lambda mit IaC erfahren möchten, bevor Sie diese Beispiel-App bereitstellen, finden Sie unter Verwenden von Lambda mit Infrastructure as Code (IaC).

Erstellen der Quellcodedateien für die Lambda-Funktion

Erstellen Sie die folgenden Dateien in Ihrem Projektverzeichnis:

  • lambda_function.py - Python-Funktionscode für die Lambda-Funktion, die die Dateiverschlüsselung durchführt

  • requirements.txt - eine Manifestdatei, die die Abhängigkeiten definiert, die Ihr Python-Funktionscode benötigt

Erweitern Sie die folgenden Abschnitte, um den Code anzusehen und mehr über die Rolle der einzelnen Dateien zu erfahren. Um die Dateien auf Ihrem lokalen Computer zu erstellen, kopieren Sie entweder den folgenden Code und fügen Sie ihn ein oder laden Sie die Dateien aus dem GitHub-Repo „aws-lambda-developer-guide“ herunter.

Kopieren Sie den folgenden Code und fügen Sie ihn in eine Datei mit dem Namen lambda_function.py ein.

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}'
Anmerkung

In diesem Beispielcode ist ein Passwort für die verschlüsselte Datei (my-secret-password) fest im Funktionscode codiert. Schließen Sie in einer Produktionsanwendung keine sensiblen Informationen wie Passwörter in Ihren Funktionscode ein. Erstellen Sie stattdessen ein AWS Secrets Manager-Secret und verwenden Sie dann die AWS-Parameter und Secrets-Lambda-Erweiterung, um Ihre Anmeldeinformationen in Ihrer Lambda-Funktion abzurufen.

Der Python-Funktionscode enthält drei Funktionen: die Handler-Funktion, die Lambda ausführt, wenn Ihre Funktion aufgerufen wird und zwei separate Funktionen mit dem Namen add_encrypted_suffix und encrypt_pdf, die der Handler aufruft, um die PDF-Verschlüsselung durchzuführen.

Wenn Ihre Funktion von Amazon S3 aufgerufen wird, übergibt Lambda ein JSON-formatiertes Ereignisargument an die Funktion, das Details zu dem Ereignis enthält, das den Aufruf verursacht hat. In diesem Fall umfassen die Informationen den Namen des S3-Buckets und die Objektschlüssel für die hochgeladenen Dateien. Weitere Informationen zum Format des Ereignisobjekts für Amazon S3 finden Sie unter Verarbeitung von Amazon-S3-Ereignisbenachrichtigungen mit Lambda.

Ihre Funktion verwendet dann die AWS SDK für Python (Boto3), um die im Ereignisobjekt angegebenen PDF-Dateien in ihr lokales temporäres Speicherverzeichnis herunterzuladen, bevor sie sie mithilfe der pypdf-Bibliothek verschlüsselt.

Schließlich verwendet die Funktion das Boto3-SDK, um die verschlüsselte Datei in Ihrem S3-Ziel-Bucket zu speichern.

Kopieren Sie den folgenden Code und fügen Sie ihn in eine Datei mit dem Namen requirements.txt ein.

boto3 pypdf

In diesem Beispiel hat Ihr Funktionscode nur zwei Abhängigkeiten, die nicht Teil der Standard-Python-Bibliothek sind: das SDK für Python (Boto3) und das pypdf-Paket, das die Funktion zur Durchführung der PDF-Verschlüsselung verwendet.

Anmerkung

Eine Version des SDK für Python (Boto3) ist Teil der Lambda-Laufzeit, sodass Ihr Code ausgeführt werden kann, ohne Boto3 zum Bereitstellungspaket Ihrer Funktion hinzuzufügen. Um jedoch die volle Kontrolle über die Abhängigkeiten Ihrer Funktion zu behalten und mögliche Probleme mit Versionsfehlern zu vermeiden, empfiehlt es sich für Python, alle Funktionsabhängigkeiten in das Bereitstellungspaket Ihrer Funktion aufzunehmen. Weitere Informationen hierzu finden Sie unter Laufzeitabhängigkeiten in Python.

Bereitstellen der App

Sie können die Ressourcen für diese Beispiel-App entweder manuell oder mithilfe von AWS SAM erstellen und bereitstellen. In einer Produktionsumgebung empfehlen wir die Verwendung eines IaC-Tools wie AWS SAM, um schnell und wiederholbar ganze Serverless-Anwendungen ohne manuelle Prozesse bereitzustellen.

So stellen Sie Ihre App manuell bereit:

  • Erstellen Sie Quell- und Ziel-Amazon-S3-Buckets

  • Erstellen Sie eine Lambda-Funktion, die eine PDF-Datei verschlüsselt und die verschlüsselte Version in einem S3-Bucket speichert

  • Konfigurieren Sie einen Lambda-Auslöser, der Ihre Funktion aufruft, wenn Objekte in Ihren Quell-Bucket hochgeladen werden

Stellen Sie zunächst sicher, dass Python auf Ihrer Build-Maschine installiert ist.

Erstellen Sie zwei S3-Buckets

Erstellen Sie zuerst zwei S3-Buckets. Der erste Bucket ist der Quell-Bucket, in den Sie Ihre PDF-Dateien hochladen. Der zweite Bucket wird von Lambda zum Speichern der verschlüsselten Datei verwendet, wenn Sie Ihre Funktion aufrufen.

Console
So erstellen Sie die S3-Buckets (Konsole)
  1. Öffnen Sie die Seite Allzweck-Buckets in der Amazon-S3-Konsole.

  2. Wählen Sie die AWS-Region aus, die Ihrem geografischen Standort am nächsten ist. Sie können Ihre Region mithilfe der Dropdown-Liste am oberen Bildschirmrand ändern.

    Abbildung des Drop-down-Regionsmenü in der S3-Konsole
  3. Wählen Sie Create Bucket (Bucket erstellen) aus.

  4. Führen Sie unter Allgemeine Konfiguration die folgenden Schritte aus:

    1. Stellen Sie sicher, dass für Bucket-Typ die Option Allzweck ausgewählt ist.

    2. Geben Sie für den Bucket-Namen einen global eindeutigen Namen ein, der den Regeln für die Bucket-Benennung von Amazon S3 entspricht. Bucket-Namen dürfen nur aus Kleinbuchstaben, Zahlen, Punkten (.) und Bindestrichen (-) bestehen.

  5. Belassen Sie alle anderen Optionen auf ihren Standardwerten und wählen Sie Bucket erstellen aus.

  6. Wiederholen Sie die Schritte 1 bis 4, um Ihren Ziel-Bucket zu erstellen. Geben Sie unter Bucket-Name den Namen amzn-s3-demo-bucket-encrypted ein. amzn-s3-demo-bucket ist hierbei der Name des Quell-Buckets, den Sie soeben erstellt haben.

AWS CLI

Stellen Sie zunächst sicher, dass die AWS CLI auf Ihrer Build-Maschine installiert ist.

So erstellen Sie die Amazon-S3-Buckets (AWS CLI)
  1. Führen Sie den folgenden CLI-Befehl aus, um Ihren Quell-Bucket zu erstellen. Der gewählte Name für Ihren Bucket muss global eindeutig sein und den Regeln für die Benennung von Buckets von Amazon S3 entsprechen. Namen dürfen nur Kleinbuchstaben, Zahlen, Punkte (.) und Bindestriche (-) enthalten. Wählen Sie für region und LocationConstraint die AWS-Region aus, die Ihrem geografischen Standort am nächsten ist.

    aws s3api create-bucket --bucket amzn-s3-demo-bucket --region us-east-2 \ --create-bucket-configuration LocationConstraint=us-east-2

    Notieren Sie sich die gewählte Region, da Sie Ihre Lambda-Funktion im weiteren Verlauf des Tutorials in der gleichen AWS-Region erstellen müssen wie Ihren Quell-Bucket.

  2. Führen Sie den folgenden Befehl aus, um Ihren Ziel-Bucket zu erstellen. Verwenden Sie für den Bucket-Namen amzn-s3-demo-bucket-encrypted. amzn-s3-demo-bucket ist hierbei der Name des Quell-Buckets, den Sie in Schritt 1 erstellt haben. Wählen Sie für region und LocationConstraint die gleiche AWS-Region aus, die Sie auch bei der Erstellung Ihres Quell-Bucket verwendet haben.

    aws s3api create-bucket --bucket amzn-s3-demo-bucket-encrypted --region us-east-2 \ --create-bucket-configuration LocationConstraint=us-east-2

Erstellen einer Ausführungsrolle

Eine Ausführungsrolle ist eine IAM-Rolle, die einer Lambda-Funktion Zugriffsberechtigungen für AWS-Services und für Ressourcen erteilt. Fügen Sie die AWS-verwaltete Richtlinie AmazonS3FullAccess an, um Ihrer Funktion Lese- und Schreibzugriff auf Amazon S3 zu erteilen.

Console
So erstellen Sie eine Ausführungsrolle und fügen die verwaltete AmazonS3FullAccess-Richtlinie an (Konsole)
  1. Öffnen Sie die Seite Roles (Rollen) in der IAM-Konsole.

  2. Wählen Sie Create role aus.

  3. Wählen Sie unter Vertrauenswürdiger Entitätstyp die Option AWS-Service und dann für Anwendungsfall die Option Lambda aus.

  4. Wählen Sie Weiter aus.

  5. Fügen Sie die verwaltete AmazonS3FullAccess-Richtlinie wie folgt hinzu:

    1. Geben Sie unter Berechtigungsrichtlinien die Zeichenfolge AmazonS3FullAccess in das Suchfeld ein.

    2. Aktivieren Sie das Kontrollkästchen neben der Richtlinie.

    3. Wählen Sie Weiter aus.

  6. Geben Sie unter Rollendetails für Rollenname den Namen LambdaS3Role ein.

  7. Wählen Sie Rolle erstellen aus.

AWS CLI
So erstellen Sie eine Ausführungsrolle und fügen die AmazonS3FullAccess-verwaltete Richtlinie an (AWS CLI)
  1. Speichern Sie den folgenden JSON-Code in einer Datei mit dem Namen trust-policy.json: Diese Vertrauensrichtlinie ermöglicht es Lambda, die Berechtigungen der Rolle zu verwenden, indem es dem Service-Prinzipal lambda.amazonaws.com die Erlaubnis erteilt, die Aktion AWS Security Token Service (AWS STS) AssumeRole aufzurufen.

    { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
  2. Führen Sie in dem Verzeichnis, in dem Sie das JSON-Vertrauensrichtliniendokument gespeichert haben, den folgenden CLI-Befehl aus, um die Ausführungsrolle zu erstellen:

    aws iam create-role --role-name LambdaS3Role --assume-role-policy-document file://trust-policy.json
  3. Führen Sie den folgenden CLI-Befehl aus, um die AmazonS3FullAccess-verwaltete Richtlinie anzuhängen.

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

Erstellen des Bereitstellungspakets für die Funktion

Um Ihre Funktion zu erstellen, erstellen Sie ein Bereitstellungspaket, das Ihren Funktionscode und die zugehörigen Abhängigkeiten enthält. Bei der hier verwendeten Anwendung verwendet Ihr Funktionscode eine separate Bibliothek für die PDF-Verschlüsselung.

Erstellen des Bereitstellungspakets
  1. Navigieren Sie zu dem Projektverzeichnis mit den lambda_function.py- und requirements.txt-Dateien, die Sie zuvor von GitHub erstellt oder heruntergeladen haben und erstellen Sie ein neues Verzeichnis mit dem Namen package.

  2. Installieren Sie die in der requirements.txt-Datei angegebenen Abhängigkeiten in Ihrem package-Verzeichnis, indem Sie den folgenden Befehl ausführen.

    pip install -r requirements.txt --target ./package/
  3. Erstellen Sie eine .zip-Datei, die Ihren Anwendungscode und seine Abhängigkeiten enthält. Führen Sie unter Linux oder MacOS die folgenden Befehle über Ihre Befehlszeilenschnittstelle aus:

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

    Verwenden Sie unter Windows Ihr bevorzugtes ZIP-Tool, um die lambda_function.zip-Datei zu erstellen. Achten Sie darauf, dass sich die Datei lambda_function.py und die Ordner, die Ihre Abhängigkeiten enthalten, im Stammverzeichnis der ZIP-Datei befinden.

Sie können Ihr Bereitstellungspaket auch in einer virtuellen Python-Umgebung erstellen. Siehe Arbeiten mit ZIP-Dateiarchiven und Python-Lambda-Funktionen

So erstellen Sie die Lambda-Funktion:

Sie verwenden jetzt das Bereitstellungspaket, das Sie im vorherigen Schritt erstellt haben, um Ihre Lambda-Funktion bereitzustellen.

Console
So erstellen Sie die Funktion (Konsole)

Wenn Sie Ihre Lambda-Funktion über die Konsole erstellen möchten, erstellen Sie zunächst eine Basisfunktion, die etwas Hello-World-Code enthält. Anschließend ersetzen Sie diesen Code durch Ihren eigenen Funktionscode, indem Sie die im vorherigen Schritt erstellte ZIP- oder Datei hochladen.

Um sicherzustellen, dass Ihre Funktion beim Verschlüsseln großer PDF-Dateien nicht zu einem Timeout kommt, konfigurieren Sie die Speicher- und Timeout-Einstellungen der Funktion. Sie legen auch das Protokollformat der Funktion auf JSON fest. Die Konfiguration von Protokollen im JSON-Format ist erforderlich, wenn Sie das bereitgestellte Testskript verwenden, damit es den Aufrufstatus der Funktion aus CloudWatch Logs lesen kann, um den erfolgreichen Aufruf zu bestätigen.

  1. Öffnen Sie die Seite Funktionen der Lambda-Konsole.

  2. Stellen Sie sicher, dass Sie in derselben AWS-Region arbeiten, in der Sie Ihren S3-Bucket erstellt haben. Sie können Ihre Region mithilfe der Dropdown-Liste am oberen Bildschirmrand ändern.

    Das Image zeigt das Dropdown-Regionsmenü in der Lambda-Konsole.
  3. Wählen Sie Funktion erstellen.

  4. Wählen Sie Author from scratch aus.

  5. Führen Sie unter Basic information (Grundlegende Informationen) die folgenden Schritte aus:

    1. Geben Sie für Function name (Funktionsname) EncryptPDF ein.

    2. Wählen Sie für Laufzeit die Option Python 3.12 aus.

    3. Wählen Sie für Architektur x86_64 aus.

  6. Fügen Sie die Ausführungsrolle, die Sie im vorherigen Schritt erstellt haben, wie folgt hinzu:

    1. Erweitern Sie den Abschnitt Ändern der standardmäßigen Ausführungsrolle.

    2. Wählen Sie Eine vorhandene Rolle verwenden aus.

    3. Wählen Sie unter Bestehende Rolle Ihre Rolle (LambdaS3Role) aus.

  7. Wählen Sie Funktion erstellen.

So laden Sie den Funktionscode hoch (Konsole)
  1. Wählen Sie im Bereich Codequelle die Option Hochladen von aus.

  2. Wählen Sie die ZIP-Datei aus.

  3. Klicken Sie auf Upload.

  4. Wählen Sie in der Dateiauswahl Ihre ZIP-Datei und anschließend Öffnen aus.

  5. Wählen Sie Speichern.

Um den Funktionsspeicher und das Timeout (Konsole) zu konfigurieren
  1. Wählen Sie die Registerkarte Konfiguration für Ihre Funktion.

  2. Wählen Sie im Bereich Allgemeine Konfiguration die Option Bearbeiten aus.

  3. Stellen Sie Speicher auf 256 MB und Timeout auf 15 Sekunden ein.

  4. Wählen Sie Speichern.

So konfigurieren Sie das Protokollformat (Konsole)
  1. Wählen Sie die Registerkarte Konfiguration für Ihre Funktion.

  2. Wählen Sie Überwachungs- und Betriebstools aus.

  3. Wählen Sie im Bereich Protokollierungskonfiguration die Option Bearbeiten aus.

  4. Wählen Sie für die Konfiguration der Protokollierung JSON aus.

  5. Wählen Sie Speichern.

AWS CLI
So erstellen Sie die Funktion (AWS CLI)
  • Führen Sie den folgenden Befehl in dem Verzeichnis aus, das Ihre lambda_function.zip-Datei enthält. Ersetzen Sie region für den Parameter us-east-2 durch die Region, in der Sie Ihre S3-Buckets erstellt haben.

    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-east-2 \ --logging-config LogFormat=JSON

Konfigurieren von Amazon-S3-Auslöser zum Aufrufen der Funktion

Damit Ihre Lambda-Funktion ausgeführt wird, wenn Sie eine Datei in Ihren Quell-Bucket hochladen, müssen Sie einen Auslöser für Ihre Funktion konfigurieren. Sie können den Amazon-S3-Auslöser entweder über die Konsole oder mithilfe der AWS CLI konfigurieren.

Wichtig

Mit diesem Verfahren wird der S3-Bucket so konfiguriert, dass die Funktion jedes Mal aufgerufen wird, wenn ein Objekt im Bucket erstellt wird. Konfigurieren Sie dieses Verhalten nur für den Quell-Bucket. Wenn Ihre Lambda-Funktion Objekte in dem Bucket erstellt, der sie aufruft, kann es passieren, dass Ihre Funktion kontinuierlich in einer Schleife aufgerufen wird. Dies kann unerwartete Gebühren für Ihr AWS-Konto zur Folge haben.

Console
So konfigurieren Sie den Amazon-S3-Auslöser (Konsole)
  1. Öffnen Sie die Seite Funktionen der Lambda-Konsole und wählen Sie Ihre Funktion (EncryptPDF) aus.

  2. Wählen Sie Add trigger.

  3. Wählen Sie S3 aus.

  4. Wählen Sie unter Bucket Ihren Quell-Bucket aus.

  5. Wählen Sie unter Ereignistypen die Option Alle Objekterstellungsereignisse aus.

  6. Aktivieren Sie unter Rekursiver Aufruf das Kontrollkästchen, um zu bestätigen, dass die Verwendung desselben S3-Buckets für die Ein- und Ausgabe nicht empfohlen wird. Weitere Informationen zu rekursiven Aufrufmustern in Lambda finden Sie bei Serverless Land unter Recursive patterns that cause run-away Lambda functions.

  7. Wählen Sie Hinzufügen aus.

    Wenn Sie einen Auslöser über die Lambda-Konsole erstellen, erstellt Lambda automatisch eine ressourcenbasierte Richtlinie, um dem von Ihnen ausgewählten Dienst die Berechtigung zum Aufrufen Ihrer Funktion zu erteilen.

AWS CLI
So konfigurieren Sie den Amazon-S3-Auslöser (AWS CLI)
  1. Fügen Sie Ihrer Funktion eine ressourcenbasierte Richtlinie hinzu, die es Ihrem Amazon-S3-Quell-Bucket ermöglicht, Ihre Funktion aufzurufen, wenn Sie eine Datei hinzufügen. Eine ressourcenbasierte Richtlinienanweisung erteilt anderen AWS-Services die Berechtigung zum Aufrufen Ihrer Funktion. Führen Sie den folgenden CLI-Befehl aus, um Amazon S3 die Berechtigung zum Aufrufen Ihrer Funktion zu erteilen. Ersetzen Sie dabei den Parameter source-account durch Ihre eigene AWS-Konto-ID und verwenden Sie Ihren eigenen Quell-Bucket-Namen.

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

    Die mit diesem Befehl definierte Richtlinie ermöglicht es Amazon S3 nur, Ihre Funktion aufzurufen, wenn eine Aktion in Ihrem Quell-Bucket ausgeführt wird.

    Anmerkung

    Namen von S3-Buckets sind zwar global eindeutig, trotzdem empfiehlt es sich, bei der Verwendung ressourcenbasierter Richtlinien anzugeben, dass der Bucket zu Ihrem Konto gehören muss. Der Grund: Wenn Sie einen Bucket löschen, kann ein anderes AWS-Konto einen Bucket mit dem gleichen Amazon-Ressourcennamen (ARN) erstellen.

  2. Speichern Sie den folgenden JSON-Code in einer Datei mit dem Namen notification.json: Wenn dieser JSON-Code auf Ihren Quell-Bucket angewendet wird, wird der Bucket so konfiguriert, dass er jedes Mal, wenn ein neues Objekt hinzugefügt wird, eine Benachrichtigung an Ihre Lambda-Funktion sendet. Ersetzen Sie die AWS-Konto-Nummer und die AWS-Region im ARN der Lambda-Funktion durch Ihre eigene Kontonummer und Region.

    { "LambdaFunctionConfigurations": [ { "Id": "EncryptPDFEventConfiguration", "LambdaFunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:EncryptPDF", "Events": [ "s3:ObjectCreated:Put" ] } ] }
  3. Führen Sie den folgenden CLI-Befehl aus, um die Benachrichtigungseinstellungen in der von Ihnen erstellten JSON-Datei auf Ihren Quell-Bucket anzuwenden. Ersetzen Sie dabei amzn-s3-demo-bucket durch den Namen Ihres Quell-Buckets.

    aws s3api put-bucket-notification-configuration --bucket amzn-s3-demo-bucket \ --notification-configuration file://notification.json

    Weitere Informationen zu dem put-bucket-notification-configuration Befehl und der notification-configuration Option finden Sie unter put-bucket-notification-configuration in der AWS CLI-Befehlsreferenz.

Stellen Sie zunächst sicher, dass Docker und die neueste Version von AWS SAM CLI auf Ihrer Build-Maschine installiert sind.

  1. Kopieren Sie im Projektverzeichnis den folgenden Code und fügen Sie ihn in eine Datei namens template.yaml ein. Ersetzen Sie die Platzhalter-Bucket-Namen:

    • Ersetzen Sie für den Quell-Bucket amzn-s3-demo-bucket durch einen beliebigen Namen, der den Benennungsregeln für S3-Buckets entspricht.

    • Ersetzen Sie für den Zielbereich amzn-s3-demo-bucket-encrypted durch <source-bucket-name>-encrypted, wobei <source-bucket> der Name ist, den Sie für Ihren Quellbereich gewählt haben.

    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: amzn-s3-demo-bucket EncryptedPDFBucket: Type: AWS::S3::Bucket Properties: BucketName: amzn-s3-demo-bucket-encrypted

    Die AWS SAM-Vorlage definiert die Ressourcen, die Sie für Ihre App erstellen. In diesem Beispiel definiert die Vorlage eine Lambda-Funktion unter Verwendung des AWS::Serverless::Function-Typs und zwei S3-Buckets unter Verwendung des AWS::S3::Bucket-Typs. Die in der Vorlage angegebenen Bucket-Namen sind Platzhalter. Bevor Sie die Anwendung mit AWS SAM bereitstellen, müssen Sie die Vorlage bearbeiten, um die Buckets mit global eindeutigen Namen umzubenennen, die den S3-Bucket-Benennungsregeln entsprechen. Dieser Schritt wird unter Stellen Sie die Ressourcen bereit mit AWS SAM näher erläutert.

    Die Definition der Lambda-Funktionsressource konfiguriert einen Trigger für die Funktion mithilfe der S3Event-Event-Eigenschaft. Dieser Trigger bewirkt, dass Ihre Funktion immer dann aufgerufen wird, wenn ein Objekt in Ihrem Quell-Bucket erstellt wird.

    Die Funktionsdefinition spezifiziert auch eine AWS Identity and Access Management-(IAM)-Richtlinie, die der Ausführungsrolle der Funktion zugeordnet werden soll. Die AWS-verwaltete Richtlinie AmazonS3FullAccess gibt Ihrer Funktion die Berechtigungen, die sie zum Lesen und Schreiben von Objekten in Amazon S3 benötigt.

  2. Führen Sie den folgenden Befehl in dem Verzeichnis aus, in dem Sie Ihre template.yaml-, lambda_function.py- und requirements.txt-Dateien gespeichert haben.

    sam build --use-container

    Dieser Befehl sammelt die Build-Artefakte für Ihre Anwendung und platziert sie im richtigen Format und am richtigen Ort, um sie bereitzustellen. Wenn Sie die Option --use-container angeben, wird Ihre Funktion innerhalb eines Lambda-ähnlichen Docker-Containers erstellt. Wir verwenden es hier, sodass Sie Python 3.12 nicht auf Ihrem lokalen Computer installiert haben müssen, damit der Build funktioniert.

    Während des Erstellungsprozesses sucht AWS SAM nach dem Lambda-Funktionscode an dem Ort, den Sie mit der Eigenschaft CodeUri in der Vorlage angegeben haben. In diesem Fall haben wir das aktuelle Verzeichnis als Standort (./) angegeben.

    Wenn eine requirements.txt-Datei vorhanden ist, verwendet AWS SAM sie, um die angegebenen Abhängigkeiten zu sammeln. Standardmäßig erstellt AWS SAM ein .zip-Bereitstellungspaket mit Ihrem Funktionscode und den Abhängigkeiten. Sie können Ihre Funktion auch mithilfe der PackageType-Eigenschaft als Container-Image bereitstellen.

  3. Führen Sie den folgenden Befehl aus, um Ihre Anwendung bereitzustellen und die in Ihrer AWS SAM-Vorlage angegebenen Lambda- und Amazon S3-Ressourcen zu erstellen.

    sam deploy --guided

    Wenn Sie die --guided-Markierung verwenden, werden Ihnen in AWS SAM Eingabeaufforderungen angezeigt, die Sie durch den Bereitstellungsprozess führen. Akzeptieren Sie für diese Bereitstellung die Standardoptionen, indem Sie die Eingabetaste drücken.

AWS SAM erstellt während des Bereitstellungsprozesses die folgenden Ressourcen in Ihrem AWS-Konto:

  • Ein CloudFormation-Stack mit dem Namen sam-app

  • Eine Lambda-Funktion mit dem Namen EncryptPDF

  • Zwei S3-Buckets mit den Namen, die Sie bei der Bearbeitung der template.yaml AWS SAM Vorlagendatei ausgewählt haben

  • Eine IAM-Ausführungsrolle für Ihre Funktion mit dem Namensformat sam-app-EncryptPDFFunctionRole-2qGaapHFWOQ8

Wenn AWS SAM die Erstellung Ihrer Ressourcen abgeschlossen hat, sollten Sie die folgende Meldung sehen:

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

Testen der Anwendung

Um Ihre App zu testen, laden Sie eine PDF-Datei in Ihren Quell-Bucket hoch und bestätigen, dass Lambda eine verschlüsselte Version der Datei in Ihrem Ziel-Bucket erstellt. In diesem Beispiel können Sie dies entweder manuell über die Konsole oder das AWS CLI oder mit Hilfe des mitgelieferten Testskripts testen.

Für Produktionsanwendungen können Sie herkömmliche Testmethoden und -techniken wie Modultests verwenden, um die korrekte Funktionsweise Ihres Lambda-Funktionscodes zu überprüfen. Es empfiehlt sich auch, Tests wie die im bereitgestellten Testskript enthaltenen durchzuführen, bei denen Integrationstests mit echten, cloudbasierten Ressourcen durchgeführt werden. Integrationstests in der Cloud bestätigen, dass Ihre Infrastruktur korrekt bereitgestellt wurde und dass Ereignisse erwartungsgemäß zwischen verschiedenen Diensten ablaufen. Weitere Informationen hierzu finden Sie unter Wie man Serverless-Funktionen und Anwendungen testet.

Sie können Ihre Funktion manuell testen, indem Sie Ihrem Amazon-S3-Quell-Bucket eine PDF-Datei hinzufügen. Wenn Sie Ihre Datei dem Quell-Bucket hinzufügen, sollte Ihre Lambda-Funktion automatisch aufgerufen werden und eine verschlüsselte Version der Datei in Ihrem Ziel-Bucket speichern.

Console
So testen Sie Ihre Anwendung, indem Sie eine Datei hochladen (Konsole)
  1. Um eine PDF-Datei in Ihren S3-Bucket hochzuladen, gehen Sie wie folgt vor:

    1. Öffnen Sie die Seite Buckets der Amazon-S3-Konsole und wählen Sie Ihren Quell-Bucket aus.

    2. Klicken Sie auf Upload.

    3. Wählen Sie Dateien hinzufügen und anschließend über die Dateiauswahl die PDF-Datei aus, die Sie hochladen möchten.

    4. Wählen Sie Öffnen und anschließend Hochladen aus.

  2. Überprüfen Sie, ob Lambda eine verschlüsselte Version Ihrer PDF-Datei in Ihrem Ziel-Bucket gespeichert hat, indem Sie Folgendes tun:

    1. Navigieren Sie wieder zur Seite Buckets der Amazon-S3-Konsole und wählen Sie Ihren Ziel-Bucket aus.

    2. Im Objektbereich sollten Sie nun eine Datei mit dem Namen filename_encrypted.pdf-Format sehen (wobei filename.pdf der Name der Datei ist, die Sie in Ihren Quell-Bucket hochgeladen haben). Um Ihre verschlüsselte PDF-Datei herunterzuladen, wählen Sie die Datei aus und wählen Sie dann Herunterladen aus.

    3. Bestätigen Sie, dass Sie die heruntergeladene Datei mit dem Passwort öffnen können, mit dem Ihre Lambda-Funktion sie geschützt hat (my-secret-password).

AWS CLI
So testen Sie Ihre Anwendung, indem Sie eine Datei hochladen (AWS CLI)
  1. Führen Sie in dem Verzeichnis, das die hochzuladende PDF-Datei enthält, den folgenden CLI-Befehl aus. Ersetzen Sie dabei den Parameter --bucket durch den Namen Ihres Quell-Buckets. Verwenden Sie für die --key- und --body-Parameter den Dateinamen Ihres Testbilds.

    aws s3api put-object --bucket amzn-s3-demo-bucket --key test.pdf --body ./test.pdf
  2. Vergewissern Sie sich, dass Ihre Funktion eine verschlüsselte Version Ihrer Datei erstellt und in Ihrem S3-Ziel-Bucket gespeichert hat. Führen Sie den folgenden CLI-Befehl aus und ersetzen Sie dabei amzn-s3-demo-bucket-encrypted durch den Namen Ihres eigenen Ziel-Buckets:

    aws s3api list-objects-v2 --bucket amzn-s3-demo-bucket-encrypted

    Wenn Ihre Funktion erfolgreich ausgeführt wird, erhalten Sie eine Ausgabe wie die folgende. Ihr Ziel-Bucket sollte eine Datei mit dem Namensformat <your_test_file>_encrypted.pdf enthalten, wobei <your_test_file> der Name der von Ihnen hochgeladenen Datei ist.

    { "Contents": [ { "Key": "test_encrypted.pdf", "LastModified": "2023-06-07T00:15:50+00:00", "ETag": "\"7781a43e765a8301713f533d70968a1e\"", "Size": 2763, "StorageClass": "STANDARD" } ] }
  3. Führen Sie den folgenden CLI-Befehl aus, um die Datei herunterzuladen, die Lambda in Ihrem Ziel-Bucket gespeichert hat. Ersetzen Sie den --bucket-Parameter durch den Namen Ihres Ziel-Buckets. Verwenden Sie für den Parameter --key den Dateinamen <your_test_file>_encrypted.pdf, wobei <your_test_file> der Name der von Ihnen hochgeladenen Testdatei ist.

    aws s3api get-object --bucket amzn-s3-demo-bucket-encrypted --key test_encrypted.pdf my_encrypted_file.pdf

    Dieser Befehl lädt die Datei in Ihr aktuelles Verzeichnis herunter und speichert sie als my_encrypted_file.pdf.

  4. Bestätigen Sie, dass Sie die heruntergeladene Datei mit dem Passwort öffnen können, mit dem Ihre Lambda-Funktion sie geschützt hat (my-secret-password).

Erstellen Sie die folgenden Dateien in Ihrem Projektverzeichnis:

  • test_pdf_encrypt.py - ein Testskript, mit dem Sie Ihre Anwendung automatisch testen können

  • pytest.ini - eine Konfigurationsdatei für das Testskript

Erweitern Sie die folgenden Abschnitte, um den Code anzusehen und mehr über die Rolle der einzelnen Dateien zu erfahren.

Kopieren Sie den folgenden Code und fügen Sie ihn in eine Datei mit dem Namen test_pdf_encrypt.py ein. Ersetzen Sie unbedingt die Platzhalter-Bucket-Namen:

  • Ersetzen Sie in der test_source_bucket_available-Funktion amzn-s3-demo-bucket durch den Namen Ihres Quell-Eimers.

  • Ersetzen Sie in der Funktion test_encrypted_file_in_bucket amzn-s3-demo-bucket-encrypted durch source-bucket-encrypted, wobei source-bucket> der Name Ihres Quell-Eimers ist.

  • Ersetzen Sie in der cleanup-Funktion amzn-s3-demo-bucket durch den Namen Ihres Quell-Buckets und ersetzen Sie amzn-s3-demo-bucket-encrypted durch den Namen Ihres Ziel-Buckets.

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 = 'amzn-s3-demo-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 = 'amzn-s3-demo-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 = 'amzn-s3-demo-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 = 'amzn-s3-demo-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

Das automatisierte Testskript führt drei Testfunktionen aus, um den korrekten Betrieb Ihrer App zu bestätigen:

  • Der Test test_source_bucket_available bestätigt, dass Ihr Quell-Bucket erfolgreich erstellt wurde, indem eine Test-PDF-Datei in den Bucket hochgeladen wird.

  • Der Test test_lambda_invoked fragt den neuesten CloudWatch Logs-Protokollstream für Ihre Funktion ab, um zu bestätigen, dass Ihre Lambda-Funktion beim Hochladen der Testdatei ausgeführt wurde und erfolgreich gemeldet wurde.

  • Der Test test_encrypted_file_in_bucket bestätigt, dass Ihr Ziel-Bucket die verschlüsselte test_encrypted.pdf-Datei enthält.

Nachdem all diese Tests ausgeführt wurden, führt das Skript einen zusätzlichen Bereinigungsschritt aus, um die test.pdf- und test_encrypted.pdf-Dateien sowohl aus Ihrem Quell- als auch aus Ihrem Ziel-Bucket zu löschen.

Wie bei der AWS SAM-Vorlage sind die in dieser Datei angegebenen Bucket-Namen Platzhalter. Bevor Sie den Test ausführen, müssen Sie diese Datei mit den echten Bucket-Namen Ihrer App bearbeiten. Dieser Schritt wird unter Testen Sie die App mit dem automatisierten Skript näher erläutert

Kopieren Sie den folgenden Code und fügen Sie ihn in eine Datei mit dem Namen pytest.ini ein.

[pytest] markers = order: specify test execution order

Dies ist erforderlich, um die Reihenfolge anzugeben, in der die Tests im test_pdf_encrypt.py-Skript ausgeführt werden.

Um die Tests durchzuführen, gehen Sie wie folgt vor:

  1. Stellen Sie sicher, dass das pytest-Modul in Ihrer lokalen Umgebung installiert ist. Sie können pytest installieren, indem Sie den folgenden Befehl ausführen:

    pip install pytest
  2. Speichern Sie eine PDF-Datei mit dem Namen test.pdf in dem Verzeichnis, das die test_pdf_encrypt.py- und pytest.ini-Dateien enthält.

  3. Öffnen Sie ein Terminal- oder Shell-Programm und führen Sie den folgenden Befehl in dem Verzeichnis aus, das die Testdateien enthält.

    pytest -s -v

    Wenn der Test abgeschlossen ist, sollten Sie eine Ausgabe wie die folgende sehen:

    ============================================================== 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 amzn-s3-demo-bucket Deleted test_encrypted.pdf from amzn-s3-demo-bucket-encrypted =============================================================== 4 passed in 7.32s ==========================================================

Nächste Schritte

Nachdem Sie diese Beispiel-App erstellt haben, können Sie den bereitgestellten Code als Grundlage verwenden, um andere Arten von Dateiverarbeitungsanwendungen zu erstellen. Ändern Sie den Code in der lambda_function.py-Datei, um die Dateiverarbeitungslogik für Ihren Anwendungsfall zu implementieren.

Viele typische Anwendungsfälle für die Dateiverarbeitung beinhalten Bildverarbeitung. Bei der Verwendung von Python enthalten die beliebtesten Bildverarbeitungsbibliotheken wie Pillow typischerweise C- oder C++-Komponenten. Um sicherzustellen, dass das Bereitstellungspaket Ihrer Funktion mit der Lambda-Ausführungsumgebung kompatibel ist, ist es wichtig, die richtige Binärdatei für die Quelldistribution zu verwenden.

Wenn Sie Ihre Ressourcen mit AWS SAM bereitstellen, müssen Sie einige zusätzliche Schritte unternehmen, um die richtige Quelldistribution in Ihr Bereitstellungspaket aufzunehmen. Da AWS SAM keine Abhängigkeiten für eine andere Plattform als Ihre Build-Maschine installiert werden, funktioniert die Angabe der richtigen Quelldistribution (.whl-Datei) in Ihrer requirements.txt-Datei nicht, wenn Ihre Build-Maschine ein Betriebssystem oder eine Architektur verwendet, die sich von der Lambda-Ausführungsumgebung unterscheidet. Stattdessen sollten Sie eine der folgenden Möglichkeiten nutzen:

  • Verwenden Sie die --use-container-Option beim Ausführen von sam build. Wenn Sie diese Option angeben, lädt AWS SAM ein Container-Basis-Image herunter, das mit der Lambda-Ausführungsumgebung kompatibel ist und erstellt das Bereitstellungspaket Ihrer Funktion in einem Docker-Container unter Verwendung dieses Images. Weitere Informationen finden Sie unter Eine Lambda-Funktion in einem bereitgestellten Container erstellen.

  • Erstellen Sie das .zip-Bereitstellungspaket Ihrer Funktion mithilfe der richtigen Binärdatei für die Quelldistribution selbst und speichern Sie die .zip-Datei in dem Verzeichnis, das Sie in der AWS SAM-Vorlage als CodeUri angeben. Weitere Informationen zum Erstellen von .zip-Bereitstellungspaketen für Python mithilfe von Binärverteilungen finden Sie unter ZIP-Bereitstellungspakets mit Abhängigkeiten erstellen und ZIP-Bereitstellungspakete mit nativen Bibliotheken erstellen.