Como mapear subdomínio no CloudFront para o mesmo nome no S3?

2

Eu tenho procurado uma maneira de fazer o seguinte, se alguém puder me esclarecer, será muito apreciado.

por exemplo. os seguintes mapeamentos seriam possíveis em uma única instância do CloudFront?

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

e assim por diante ..

O caso de uso é que eu quero poder implantar tantos ambientes para cada ramificação do git que mapeia para um bucket no S3 que existe. Isso tudo seria possível?

    
por Van Nguyen 10.09.2018 / 06:59

1 resposta

2

Sim, é possível, mas você precisará usar o aprimoramento do Lambda @ Edge no CloudFront para manipular os parâmetros de solicitação antes de enviar a solicitação ao intervalo.

Eu descrevi uma solução possível em esta postagem no fórum oficial . Essa mesma solução está incluída abaixo.

O Lambda @ Edge permite o acesso programático às solicitações ou respostas HTTP à medida que o CloudFront as processa, fornecendo essencialmente ganchos de gatilho. A transação HTTP é apresentada como um objeto javascript que você pode observar e modificar e, em seguida, retornar o controle para o CloudFront.

Para este aplicativo, você precisa usar o ponto de extremidade de hospedagem do site como seu nome de domínio de origem no CloudFront config (ou seja, não selecione o intervalo no menu suspenso - digite-o, usando o "s3- website "hostname) e você precisa colocar na lista de permissões o Host header para encaminhar para a origem, mesmo que na verdade não o esteja encaminhando (estaremos lendo e manipulando, junto com o caminho) e mesmo assim Normalmente, encaminhá-lo para uma origem S3 não funcionaria como planejado ... mas precisamos informar ao CloudFront para colocar na lista de permissões para que ele possa ser lido e manipulado.

Configure a seguinte função Lambda como acionador de solicitação de origem. Esse disparador é acionado depois que o cache do CloudFront é verificado e ocorre um erro de cache, e antes que a solicitação seja enviada para o servidor de origem (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);
};

Lembre-se também de definir o TTL mínimo de cache de erro como 0 para evitar respostas de erro de cache do CloudFront. Esta é uma configuração separare de min / default / max TTL nas configurações do comportamento do cache. O padrão é 5 minutos, o que faz sentido, mas complica a solução de problemas se você não antecipar esse comportamento.

Observe que as funções do Lambda @ Edge agora podem usar a v6.10 ou v8.10 Ambiente de tempo de execução do Node.js. O exemplo acima foi originalmente escrito para v6.10, mas é compatível com qualquer tempo de execução porque na v8.10 o manipulador tem mais opções: ele pode usar async / wait, ele pode retornar uma promessa diretamente ou pode ser escrito como mostrado acima para usar a interface de retorno de chamada.

    
por 10.09.2018 / 10:45