Как сопоставить поддомен в CloudFront с тем же именем в S3?

Как сопоставить поддомен в CloudFront с тем же именем в S3?

Я искал способ сделать следующее, если кто-то сможет меня просветить, буду очень признателен.

например, будут ли возможны следующие сопоставления в одном экземпляре CloudFront?

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

и так далее..

Вариант использования: я хочу иметь возможность развернуть столько сред для каждой ветки git, которая отображается на существующий контейнер на S3. Будет ли все это возможно?

решение1

Да, это возможно, но вам придется использовать расширение Lambda@Edge для CloudFront, чтобы манипулировать параметрами запроса перед отправкой запроса в контейнер.

Я описал одно из возможных решений вэтот официальный пост на форуме. Это же решение приведено ниже.

Lambda@Edge обеспечивает программный доступ к HTTP-запросам или ответам, пока CloudFront обрабатывает их, по сути, предоставляя триггерные хуки. HTTP-транзакция представлена ​​как объект javascript, который вы можете наблюдать и изменять, а затем возвращать управление CloudFront.

Для этого приложения вам необходимо использовать конечную точку хостинга веб-сайта контейнера в качестве имени домена источника в конфигурации CloudFront (т. е. не выбирайте контейнер из раскрывающегося списка, а введите его, используя соответствующее имя хоста «s3-website»), и вам необходимо добавить заголовок в белый список Hostдля пересылки в источник, даже если мы фактически не будем его пересылать (мы будем читать его, а затем манипулировать им вместе с путем) и даже если обычно пересылка этого в источник S3 не будет работать так, как задумано... но нам нужно указать CloudFront добавить его в белый список, чтобы его можно было читать и манипулировать.

Настройте следующую функцию Lambda как триггер Origin Request. Этот триггер срабатывает после проверки кэша CloudFront и возникновения промаха кэша, и до отправки запроса на исходный сервер (S3).

'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);
};

Не забудьте также установить свойошибка кэширования минимального TTL до 0чтобы избежать ответов об ошибках кэша CloudFront. Это отдельная настройка от min/default/max TTL в настройках Cache Behavior. Значение по умолчанию — 5 минут, что имеет смысл, но усложняет устранение неполадок, если вы не ожидаете такого поведения.


Обратите внимание, что функции Lambda@Edge теперь могут использовать либо v6.10, либоверсия 8.10Среда выполнения Node.js. Приведенный выше пример изначально был написан для v6.10, но совместим с любой средой выполнения, поскольку в v8.10 обработчик имеет больше возможностей: он может использовать async/await, он может напрямую возвращать обещание или его можно написать, как показано выше, для использования интерфейса обратного вызова.

Связанный контент