Blog

Pretty URLs in AWS CloudFront nutzen

Amazon Web Services

Was selbstverständlich erscheint und in klassischen AWS S3-Buckets auch wunderbar funktioniert, ist die Sache mit den Pretty URLs, genauer gesagt den Standardstammobjekten.

Diese müssen in AWS CloudFront nämlich explizit gesetzt werden, denn es findet keine automatische Weiterleitung statt. Das klingt komplizierter, als es eigentlich ist.

Weiterleitungsverhalten eines klassischen AWS S3-Buckets

Ein klassischer AWS S3-Bucket leitet Anfragen für ein Unterverzeichnis automatisch an das Standardstammobjekt, das heißt, dass eine Anfrage an http://example.com/subdirectory automatisch die Index-Datei http://example.com/subdirectoy/index.html zurückgibt.

Weiterleitungsverhalten in einer AWS CloudFront-Distribution

In CloudFront findet diese automatische Weiterleitung nicht statt, es lässt sich lediglich ein Standardstammobjekt für das Hauptverzeichnis anlegen. So leitet zwar http://example.com korrekt zu http://example.com/index.html weiter, in Unterverzeichnissen findet diese Weiterleitung aber nicht statt.

Aber ich will Pretty URLs!!!

Damit die Pretty URLs dennoch funktionieren, wird eine Lambda@Edge-Funktion benötigt. Diese Funktion wird als Reaktion auf jede Ursprungsanfrage an CloudFront ausgeführt, bevor CloudFront das Objekt vom AWS S3-Ursprung anfordert und ändert alle Anfragen, die mit einem Trailing-Slash enden in die gewünschten /index.html-Endungen.

Als Erstes wird eine AWS Lambda@Edge-Funktion ohne Vorgabe erstellt. Wichtig ist, dass dieser Funktion eine Rolle zugeordnet wird, die die Richtlinienvorlage “Grundlegende Lambda@Edge-Berechtigungen (für CloudFront-Auslöser)” enthält.

Nachdem die Funktion erstellt wurde, wird als Erstes die Region auf “US East (N. Virginia) umgestellt, denn der benötigte CloudFront-Auslöser ist nur in dieser Region verfügbar.

Als Nächstes wird folgender Code eingefügt:

<% code(“js”) do %> ‘use strict’;

const pointsToFile = uri => /\/[^/]+.[^/]+$/.test(uri);

exports.handler = (event, context, callback) => {

// Extract the request from the CloudFront event that is sent to Lambda@Edge
var request = event.Records[0].cf.request;

// Extract the URI from the request
var oldUri = request.uri;
var newUri;

if (!pointsToFile(oldUri) && !oldUri.endsWith('/')) {
  const newUri = request.querystring ? `${oldUri}/?${request.querystring}` : `${oldUri}/`;
  return callback(null, {
    body: '',
    status: '301',
    statusDescription: 'Moved Permanently',
    headers: {
      location: [{
        key: 'Location',
        value: newUri,
      }],
    }
  });
} else {
  newUri = oldUri;
}

// Match any '/' that occurs at the end of a URI. Replace it with a default index
newUri = newUri.replace(/\/$/, '\/index.html');

// Log the URI as received by CloudFront and the new URI to be used to fetch from origin
console.log("Old URI: " + oldUri);
console.log("New URI: " + newUri);

// Replace the received URI with the URI that includes the index page
request.uri = newUri;

// Return to CloudFront
return callback(null, request);

}; <% end %>

Jetzt wird der Funktion als letzter Schritt noch der CloudFrontAuslöser hinzugefügt. Hierfür wird die ID der CloudFront-Distribution benötigt, damit die Funktion der CloudFront-Distribution zugeordnet wird. Nach einigen Minuten ist der Veröffentlichungsprozess abgeschlossen und die Pretty URLs funktionieren auch in CloudFront.

Kaffeekasse

Der Artikel hat Dir weitergeholfen? Sehr schön! Dann spendier uns doch ein 🍺 oder einen ☕ auf Steady.com.

Supporte uns auf Steady.com
Lukas Becker, geschäftsführender Gesellschafter der Digitalagentur candyblue UG (haftungsbeschränkt) aus Kassel 1