Wie ordnet man eine Subdomäne in CloudFront demselben Namen in S3 zu?

Wie ordnet man eine Subdomäne in CloudFront demselben Namen in S3 zu?

Ich habe nach einer Möglichkeit gesucht, Folgendes zu tun. Wenn mich jemand aufklären könnte, wäre ich sehr dankbar.

Wären beispielsweise die folgenden Zuordnungen in einer einzelnen CloudFront-Instanz möglich?

feature-a.domain.com => dev-bucket/feature-a
feature-b.domain.com => dev-bucket/feature-b
staging.domain.com   => dev-bucket/staging

und so weiter..

Der Anwendungsfall ist, dass ich für jeden Git-Zweig so viele Umgebungen bereitstellen möchte, wie einem vorhandenen Bucket auf S3 zugeordnet sind. Wäre das alles möglich?

Antwort1

Ja, das ist möglich, aber Sie müssen die Lambda@Edge-Erweiterung für CloudFront verwenden, um die Anforderungsparameter zu bearbeiten, bevor Sie die Anforderung an den Bucket senden.

Eine mögliche Lösung habe ich indieser offizielle Forumsbeitrag. Dieselbe Lösung finden Sie weiter unten.

Lambda@Edge ermöglicht programmgesteuerten Zugriff auf die HTTP-Anfragen oder -Antworten, während CloudFront sie verarbeitet – und stellt im Wesentlichen Trigger-Hooks bereit. Die HTTP-Transaktion wird als JavaScript-Objekt dargestellt, das Sie beobachten und ändern und dann die Kontrolle an CloudFront zurückgeben können.

Für diese Anwendung müssen Sie den Website-Hosting-Endpunkt des Buckets als Ihren Ursprungsdomänennamen in der CloudFront-Konfiguration verwenden (d. h. wählen Sie den Bucket nicht aus der Dropdown-Liste aus, sondern geben Sie ihn mit dem entsprechenden Hostnamen „s3-website“ ein). Außerdem müssen Sie den HostHeader zur Weiterleitung an den Ursprung auf die Whitelist setzen, obwohl wir ihn nicht wirklich weiterleiten (wir werden ihn lesen und dann zusammen mit dem Pfad bearbeiten) und obwohl die Weiterleitung an einen S3-Ursprung normalerweise nicht wie vorgesehen funktionieren würde … aber wir müssen CloudFront anweisen, ihn auf die Whitelist zu setzen, damit er gelesen und bearbeitet werden kann.

Konfigurieren Sie die folgende Lambda-Funktion als Origin Request-Trigger. Dieser Trigger wird ausgelöst, nachdem der CloudFront-Cache überprüft wurde und ein Cache-Fehler auftritt und bevor die Anforderung an den Ursprungsserver (S3) gesendet wird.

'use strict';

// https://serverfault.com/a/930191/153161
// if the end of incoming Host header matches this string, 
// strip this part and prepend the remaining characters onto the request path,
// along with a new leading slash (otherwise, the request will be handled
// with an unmodified path, at the root of the bucket)

// set this to what we should remove from the incoming hostname, including the leading dot.

const remove_suffix = '.example.com';

// provide the correct origin hostname here so that we send the correct 
// Host header to the S3 website endpoint
// this is the same value as "origin domain name" in the cloudfront distribution configuration

const origin_hostname = 'example-bucket.s3-website-us-east-1.amazonaws.com';

exports.handler = (event, context, callback) => {
  const request = event.Records[0].cf.request;
  const headers = request.headers;
  const host_header = headers.host[0].value;

  if(host_header.endsWith(remove_suffix))
  {
    // prepend '/' + the subdomain onto the existing request path ("uri")
    request.uri = '/' + host_header.substring(0,host_header.length - remove_suffix.length) + request.uri;
  }

  // fix the host header so that S3 understands the request
  // we have to do this even if the above if() didn't match
  headers.host[0].value = origin_hostname;

  // return control to CloudFront with the modified request
  return callback(null,request);
};

Denken Sie auch daran, IhreFehler beim Zwischenspeichern des minimalen TTL auf 0um Fehlerantworten im CloudFront-Cache zu vermeiden. Dies ist eine separate Einstellung von min./standardmäßiger/max. TTL in den Cache-Verhaltenseinstellungen. Der Standardwert beträgt 5 Minuten, was sinnvoll ist, aber die Fehlerbehebung erschwert, wenn Sie dieses Verhalten nicht erwarten.


Beachten Sie, dass Lambda@Edge-Funktionen jetzt entweder die Version v6.10 oderVersion 8.10Node.js-Laufzeitumgebung. Das obige Beispiel wurde ursprünglich für v6.10 geschrieben, ist aber mit beiden Laufzeiten kompatibel, da der Handler in v8.10 mehr Optionen hat: Er kann async/await verwenden, er kann direkt ein Promise zurückgeben oder er kann wie oben gezeigt geschrieben werden, um die Callback-Schnittstelle zu verwenden.

verwandte Informationen