Suchen

Microservices und Cloud-native Apps in der Praxis, Teil 2 Setup eines On-the-fly Image-Resizers

Autor / Redakteur: Dipl. -Ing. Thomas Drilling / Stephan Augsten

Ein auf AWS Lambda basierender Image-Resizer, der On-the-Fly arbeitet, bietet mehr Zuverlässigkeit und Agilität als eine herkömmliche Bildanpassung. Dieser zweite Teil unseres Praxisbeispiels demonstriert die Umsetzung mit AWS Lamda, API Gateway und Amazon S3.

Firma zum Thema

Finaler Test unseres Image Resizers mit einem alternativen Bildformat.
Finaler Test unseres Image Resizers mit einem alternativen Bildformat.
(Bild: Drilling / AWS)

Der komplette quelloffene Code des Beispiels wird übrigens wie im Teil 1 erläutert von AWS auf GitHub im Repo awslabs/serverless-image-resizing bereitgestellt. Wer den Service einfach nur nutzen und nicht zu Lernzwecken nachvollziehen möchte kann die benötigten Ressourcen erstellen, indem er den Anweisungen in der README-Datei folgt.

Hierbei wird eine AWS-SAM-Vorlage (AWS Serverless Application Model) verwendet. Wir erstellen die benötigten Ressourcen in diesem Tutorial allerdings manuell. Wir beginnen mit dem S3-Bucket. Das Erstellen eines Buckets in der S3-Console sollte jedem Entwickler geläufig sein. Buckets sind regional angelegt, der Bucket-Name (Namespace) muss aber global unique sein.

Über den Tab „Permissions“ richten wir eine Bucket-Policy für den anonymen Zugriff ein, eine entsprechende Vorlage findet sich bei AWS.
Über den Tab „Permissions“ richten wir eine Bucket-Policy für den anonymen Zugriff ein, eine entsprechende Vorlage findet sich bei AWS.
(Bild: Drilling / AWS)

Wichtig ist, dass man bei den Bucket-Berechtigungen nicht pauschal öffentlichen Zugriff via Bucket-ACL erlaubt, sondern im Tab „Permissions“ eine Bucket-Policy für anonymen Zugriff einrichtet. Das benötigten Policy-Dokument in JSON kann man entweder per Policy Editor erzeugen, von Grund auf neu in den Policy-Editor eingeben oder einfach folgende Policy-Vorlage von AWS verwenden. Man muss dann lediglich den Bucket-Namen anpassen.

In den Einstellungen muss das statische Website-Hosting aktiviert werden.
In den Einstellungen muss das statische Website-Hosting aktiviert werden.
(Bild: Drilling / AWS)

Darüber hinaus muss man im Tab „Properties“ das Feature „Static website hosting“ aktivieren und dabei als „Index document“ index.html eintragen. Nach dem Speichern notiert man sich bei der Gelegenheit gleich den Namen des Website-Endpunkts ganz oben hinter „Endpoint:“.

Lambda-Funktion

Weiter geht es mit der Lambda-Funktion. Wir haben schon öfter demonstriert, wie man in der grafischen Lambda-Console eine neue Lambda-Funktion wahlweise vom Reißbrett, per Blueprint, Herunterladen des Codes von S3 oder Hochladen eines ZIPs anlegt. Um die Ausführungsrollenberechtigungen für die Funktion zu definieren, wählen wir im Abschnitt „Permissions“ bei „Choose or create an execution role“ die Option „Use an existing role“.

Erstellen der Zugriffsrolle.
Erstellen der Zugriffsrolle.
(Bild: Drilling / AWS)

Hier wählen wir dann die zuvor in IAM für den Lambda-Service erstellte Rolle. Wie das geht, haben wir ebenfalls schon häufiger demonstriert. Der JSON-Code für Richtlinien-Dokument sollte so aussehen, wobei der Bucket-Name wieder durch den eigenen zu ersetzen ist.

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
            "logs:CreateLogGroup",
            "logs:CreateLogStream",
            "logs:PutLogEvents"
         ],
         "Resource": "arn:aws:logs:*:*:*"
      },
      {
         "Effect": "Allow",
         "Action": "s3:PutObject",
         "Resource": "arn:aws:s3:::<examplebucket>/*"
      }
      ]
}

Für den Lambda-Function-Code selbst verwenden wir das von AWS bei Github bereitgestellte Code-Sample. Dieses laden wir vorher lokal herunter und stellen es dann im GUI-Dialog zur Bereitstellung einer neuen Lambda-Funktion als ZIP bereit. Die Runtime ist NodeJS. Als Trigger der Lambda-Funktion (Integration) nehmen wir nicht S3, sondern API-Gateway.

Der API-Name lautet unserem Projekt entsprechend resizer, um ihn mit der zugehörigen Lamba-Funktion in Verbindung zu bringen.
Der API-Name lautet unserem Projekt entsprechend resizer, um ihn mit der zugehörigen Lamba-Funktion in Verbindung zu bringen.
(Bild: Drilling / AWS)

Bei „API“ wählen wir „Create an API“ und bei „Security“ den Eintrag „Open“. Der API-Type ist „REST-API“. Dies erlaubt es Usern, die API-Methode aufzurufen. Der API-Name muss in diesem Fall „resizer“ lautet, damit der Trigger mit dem Code-Sample für die Lambda-Funktion zusammenpasst. Dann klicken wir auf „Add“. Den Stage ändern wir von „default“ auf „prod“.

Über den Designer bringen wir im Bereich „API-Gateway“ den kompletten Pfad zum API-Endpunkt in Erfahrung.
Über den Designer bringen wir im Bereich „API-Gateway“ den kompletten Pfad zum API-Endpunkt in Erfahrung.
(Bild: Drilling / AWS)

Im Designer sieht die Lambda-Funktion dann aus wie im vorangestellten Bild. Jetzt markieren wir in der Designer-Übersicht den mit lila Icon gekennzeichneten Trigger „API-Gateway“ und notieren uns dann im aufpoppenden Bereich „API-Gateway“ den kompletten Pfad zum API-Endpunkt (API Endpoint), in unserem Beispiel lautet er: https://umb19y0ck8.execute-api.eu-central-1.amazonaws.com/default/dit-lambda-resizer

Bei den Umgebungsvariablen müssen wir den Bucket-Namen und seine URL eintragen.
Bei den Umgebungsvariablen müssen wir den Bucket-Namen und seine URL eintragen.
(Bild: Drilling / AWS)

Etwas weiter unten im Lambda-Dialog müssen wir dann noch zwei Umgebungsvariablen hinzufügen. Hierzu klickt man bei „edit envrionment variables“ auf die Schaltfläche „Edit“ und dann auf „Add envrionment variables“. Die beiden benötigten Schlüssel geben wir im Punkt „BUCKET“ mit dem erstellten Bucket-Namen als Wert sowie in „URL" mit dem oben angegebenen S3-Website-Endpunkt an.

Die Grundeinstellungen für unsere Bucket-Umgebung.
Die Grundeinstellungen für unsere Bucket-Umgebung.
(Bild: Drilling / AWS)

Dann wählen wir in den „Basic settings“ noch als Arbeitsspeicher den Wert 1536 aus und wählen ein Zeitlimit von zehn Sekunden. Dann speichern wir sämtliche Einstellungen für die Lambda-Funktion und den Trigger.

Fehlt noch die S3-Umleitungsregel. Hierzu wechseln wir noch einmal zur S3-Console, wählen das betreffende Bucket und navigieren im Tab „Properties“ zum Feature „Static Website Hosting“ und ergänzen im Eingabefeld „Redirection rules (optional)“ folgenden XML-Eintrag:

<RoutingRules>
   <RoutingRule>
      <Condition>
         <KeyPrefixEquals/>
         <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
      </Condition>
      <Redirect>
         <Protocol>https</Protocol>
         <HostName>__YOUR_API_HOSTNAME_HERE__</HostName>
         <ReplaceKeyPrefixWith>prod/resize?key=</ReplaceKeyPrefixWith>
         <HttpRedirectCode>307</HttpRedirectCode>
      </Redirect>
   </RoutingRule>
</RoutingRules>

In der Redirection Rule ist der API-Endpunkt unserer Einstellung entsprechend anzugeben.
In der Redirection Rule ist der API-Endpunkt unserer Einstellung entsprechend anzugeben.
(Bild: Drilling / AWS)

Hierbei ist der Eintrag „YOUR_API_HOSTNAME_HERE“ durch den bei der Trigger-Konfiguration angezeigten API-Gateway-API-Endpunkt zu ersetzen. Hier verzichten wir obligatorisch auf das Protokoll und den Ressourcen-Pfad, schreiben also für unser Beispiel nur: umb19y0ck8.execute-api.eu-central-1.amazonaws.com

Testen des Image-Resizers

Jetzt laden wir zum Testen ein Bild-Sample in den Bucket hoch und versuchen nach dem Hochladen, die Größe des Bildes mithilfe des statischen Website-Hosting-Endpunkts je einmal für die Größen 300x300, 50x50 und 600x600 aufzurufen, welche dabei On-the-Fly erzeugt werden.

Testen des Image Resizers mit einem alternativen Bildformat.
Testen des Image Resizers mit einem alternativen Bildformat.
(Bild: Drilling / AWS)

Die entsprechenden Aufrufe sehen dann so aus:

https://:::<examplebucket>/<Bildgröße>/<beispielbild>.jpg


also, z. B:

https://dit-resizer.s3.eu-central-1.amazonaws.com/300x300/OAv2LyIx_400x400.jpg

(ID:46610976)

Über den Autor

Dipl. -Ing. Thomas Drilling

Dipl. -Ing. Thomas Drilling

IT-Consultant, Trainer, Freier Journalist