Funções de borda
Visão geral
As funções de borda são ferramentas de desenvolvedor poderosas para adicionar lógica personalizada na borda com o CloudFront. Funções de borda permitem que os desenvolvedores enriqueçam aplicações Web enquanto reduzem a latência e criem aplicações totalmente distribuídas. As funções de borda podem ser usadas para:
- Implementar a lógica HTTP avançada. O CloudFront fornece regras nativas, como redirecionamento de HTTP para HTTPs, roteamento para diferentes origens com base no caminho da solicitação etc... As funções de borda permitem que você vá além do nativo no CloudFront para implementar lógica HTTP avançada, como normalizar chaves de cache, reescrever URLs, operações HTTP CRUD, etc...
- Reduzir a latência das aplicações. Algumas lógicas da aplicação podem ser transferidas da origem para a borda para se beneficiar do armazenamento em cache (por exemplo, teste A/B) ou para serem executadas mais perto dos usuários (por exemplo, redirecionamentos de HTTP, encurtamento de URL, renderização de HTML). Em arquiteturas de microsserviços ou microfrontais, você pode usar funções de borda para implementar uma lógica comum (por exemplo, autorização e autenticação) uma vez no ponto de entrada da aplicação, em vez de implementá-la em cada componente separadamente.
- Proteger o perímetro das aplicações. As funções de borda podem ser usadas para aplicar controles de segurança, como controle de acesso e bloqueio geográfico avançado na borda. Isso permite reduzir a superfície de ataque de sua origem e remover custos de ajuste de escala desnecessários.
- Solicitar roteamento. Você pode usar funções de borda para rotear cada solicitação HTTP para uma origem específica com base na lógica da aplicação. Isso pode ser útil para cenários como failover avançado, balanceamento de carga de origem, arquiteturas multirregionais, migrações, roteamento de aplicações etc...
Tipos de funções de borda com o CloudFront
O CloudFront oferece dois tipos de funções de borda: CloudFront Functions e Lambda@Edge. As funções do CloudFront Functions oferecem tempos de inicialização inferiores a um milissegundo e escalam imediatamente para lidar com milhões de solicitações por segundo, o que o torna ideal para lógica leve (normalização de cache, reescrita de URL, manipulação de solicitações, autorização etc...). O Lambda@Edge é uma extensão do AWS Lambda, executado de forma distribuída em caches regionais de borda. O Lambda@Edge oferece mais poder de computação e funcionalidades avançadas, como chamadas de rede externas, embora por um custo maior e uma sobrecarga de latência. Esta documentação fornece detalhes profundos sobre as diferenças entre os dois runtimes.
Funções de borda podem ser usadas para manipular solicitações e respostas HTTP a bordo ou simplesmente para encerrar solicitações e gerar respostas em vez de fluírem upstream no CloudFront. Funções de borda podem ser configuradas para serem executadas em diferentes eventos durante o ciclo de vida de uma solicitação no CloudFront:
- Eventos de espectador: executados para cada solicitação, antes de verificar o cache do CloudFront. É ideal para normalização de cache, autorização ou inserção de cookies exclusivos. O CloudFront Functions apenas é permitido em eventos de espectador.
- Eventos de origem: executados em caso de falhas de cache, antes de acessar a origem para buscar arquivos. São ideais para gerar conteúdo ou manipular respostas antes de as armazenar em cache e encaminhar solicitações dinamicamente para diferentes origens.
Considere as seguintes práticas recomendadas:
- Associe uma função do Edge ao comportamento de cache mais específico para evitar custos desnecessários de execução de funções.
- Escolha o CloudFront Functions para casos de uso que são executados em eventos de espectador e o Lambda@Edge para casos de uso que são executados em eventos de origem.
- Recorra ao Lambda@Edge em eventos de espectador somente quando os recursos do CloudFront Functions não atenderem aos requisitos da sua lógica.
- Em eventos de espectador, você pode usar o Lambda@Edge ou o CloudFront Functions, mas não os dois (por exemplo, Lambda@Edge no evento de solicitação de espectador e o CloudFront Functions no evento de resposta de espectador).
- Saiba mais sobre restrições em funções de borda ao projetar sua aplicação.
CloudFront Functions
As funções no CloudFront Functions são escritas em JavaScript, podem ser criadas e testadas inteiramente no console e nas APIs do CloudFront e podem ser registradas em logs do CloudWatch na região us-east-1. Como desenvolvedor, você precisa escrever funções com utilização computacional inferior a 80%. As execuções que excederem cotas de utilização de computação serão restringidas pelo CloudFront, que pode ser monitorado usando métricas do CloudWatch.
Este guia de modelo de programação ajuda você a escrever funções do CloudFront Functions. Veja a seguir um exemplo de função para redirecionar usuários vindos da Alemanha para conteúdo traduzido em alemão:
function handler(event) {
var request = event.request;
var headers = request.headers;
var host = request.headers.host.value;
var country = 'DE';
var newurl = `https://${host}/de/index.html`;
if (headers['cloudfront-viewer-country']) {
var countryCode = headers['cloudfront-viewer-country'].value;
if (countryCode === country) {
var response = {
statusCode: 302,
statusDescription: 'Found',
headers: { location: { value: newurl } },
};
return response;
}
}
return request;
}
O CloudFront Functions também oferece a capacidade de desacoplar e armazenar dados persistentes separadamente do seu código por meio do CloudFront KeyValueStore. O KeyValueStore é especialmente ideal em situações nas quais os dados incorporados, como mapeamentos de redirecionamento em massa, ultrapassariam a cota de tamanho da função. Esse recurso também tem a vantagem de permitir que você atualize seus dados persistentes sem precisar modificar sua função.
Lambda@Edge
As funções do Lambda@Edge podem ser escritas em NodeJS ou Python. Elas permitem que você se beneficie da potência de um contêiner do Lambda com memória configurável (até 10 GB). Por ser baseada no AWS Lambda, uma função do Lambda@Edge é criada no console do Lambda e exclusivamente na região us-east-1. Quando você termina de criá-la e implantá-la na sua distribuição do CloudFront, este a replica globalmente em seus caches de borda regionais. Para associar uma função do Lambda@Edge a um comportamento de cache do CloudFront, primeiro você precisa publicar uma nova versão dela e depois implantá-la em seu comportamento de cache de destino. Cada atualização de função do Lambda@Edge aciona uma nova implantação do CloudFront (em contraste com o CloudFront Functions, em que somente a associação inicial aciona uma implantação do CloudFront). Considere o seguinte ao desenvolver funções do Lambda@Edge:
- Conheça as melhores práticas para usar o Lambda@Edge, especialmente em relação ao gerenciamento da simultaneidade de execuções. A simultaneidade mede o número de contêineres do Lambda em execução simultânea por região do cache de borda regional. Em cada região, a simultaneidade do Lambd@Edge tem cotas em termos de velocidade de intermitência e limite absoluto.
- Conheça as melhores práticas para buscar dados externos da sua função do Lambda@Edge.
- Os logs do Lambda@Edge são enviados aos logs do CloudWatch na região em que foram executados com um nome de grupo de logs prefixado com us-east-1. Se você precisar centralizar logs do Lambda@Edge em uma única região, considere a seguinte solução agregadora de logs do Lambda@Edge. Observe que cada execução de função gera logs para o CloudWatch Logs (em contraste com o CloudFront Functions, em que os logs são gerados somente quando escritos explicitamente no código da função). Você pode desabilitar logs do Lambda@Edge removendo permissões para enviar logs ao CloudWatch a partir do seu perfil do IAM associado.
Este guia de modelo de programação ajuda você a escrever funções do Lambda@Edge. Veja a seguir um exemplo de função que encaminha solicitações provenientes de usuários alemães para um servidor baseado na Alemanha para fins regulatórios:
'use strict';
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
if (request.headers['cloudfront-viewer-country']) {
const countryCode = request.headers['cloudfront-viewer-country'][0].value;
if (countryCode === 'DE') {
const domainName = 'origin.example.de';
request.origin.custom.domainName = domainName;
request.headers['host'] = [{ key: 'host', value: domainName }];
}
}
return request;
};