CloudFront Functions – uruchamianie własnego kodu „at the Edge„ z małym opóźnieniem i w dowolnej skali

20 maja 2021

Dzięki  Amazon CloudFront możesz bezpiecznie dostarczać swoim klientom na całym świecie dane, filmy, aplikacje i interfejsy API z niewielkimi opóźnieniami i dużymi prędkościami transferu. Aby zaoferować spersonalizowane funkcjonalności i możliwie najmniejsze opóźnienia, wiele nowoczesnych aplikacji wykonuje pewną logikę brzegowo. Przypadki użycia logiki at the edge można podzielić na dwie główne kategorie:

  • 1 Najpierw złożone operacje wymagające dużej mocy obliczeniowej, które są wykonywane, gdy obiektów nie ma w pamięci podręcznej. AWS uruchomił  Lambda@Edge w 2017 roku, aby zaoferować w pełni programowalne, bezserwerowe środowisko przetwarzania brzegowego do wdrażania szerokiej gamy złożonych dostosowań. Funkcje Lambda@Edge są wykonywane w regionalnej brzegowej pamięci podręcznej (zwykle w regionie AWS najbliżej lokalizacji krawędzi CloudFront). Na przykład podczas przesyłania strumieniowego wideo lub audio możesz użyć Lambda@Edge do tworzenia i obsługi odpowiednich segmentów w locie, zmniejszając potrzebę skalowalności źródła. Innym częstym przypadkiem użycia jest użycie Lambda@Edge i Amazon DynamoDB do tłumaczenia skróconych, przyjaznych dla użytkownika adresów URL na pełne strony docelowe adresów URL.
  • Druga kategoria przypadków użycia to proste manipulacje żądaniami/odpowiedziami HTTP, które mogą być wykonywane przez bardzo krótkotrwałe funkcje. Do takich przypadków użycia potrzebne jest elastyczne środowisko programistyczne z wydajnością, skalą i opłacalnością, które umożliwią wykonanie ich na każde żądanie.

Aby pomóc Ci w tej drugiej kategorii przypadków użycia, AWS poinformował o dostępności CloudFront Functions, nowej bezserwerowej platformy skryptowej, która umożliwia uruchamianie lekkiego kodu JavaScript w ponad 218 lokalizacjach CloudFront Edge za około 1/6 ceny Lambda@Edge.

CloudFront_Functions

Funkcje CloudFront są idealne do lekkiego przetwarzania żądań internetowych, na przykład:

  • Manipulowanie kluczem pamięci podręcznej i normalizacja: przekształcanie atrybutów żądań HTTP (takich jak adres URL, nagłówki, pliki cookie i ciągi zapytań) w celu skonstruowania tzw. cache-key, który jest unikalnym identyfikatorem obiektów w pamięci podręcznej i służy do określenia, czy obiekt już jest w pamięci podręcznej. Na przykład możesz buforować na podstawie nagłówka, który zawiera typ urządzenia użytkownika końcowego, tworząc dwie różne wersje treści dla użytkowników urządzeń mobilnych i komputerów stacjonarnych. Przekształcając atrybuty żądania, można również znormalizować wiele żądań do pojedynczego wpisu klucza pamięci podręcznej i znacznie poprawić współczynnik cache-hit.
  • Przepisywanie i przekierowywanie adresów URL: generuje odpowiedź na żądania przekierowania do innego adresu URL. Na przykład przekierowanie nieuwierzytelnionego użytkownika ze strony z ograniczeniami do formularza logowania. Przepisywania adresów URL można również używać do testów A/B.
  • Manipulowanie nagłówkiem HTTP: wyświetl, dodaj, zmodyfikuj lub usuń dowolne nagłówki żądania/odpowiedzi. Na przykład dodaj nagłówki HTTP Strict Transport Security (HSTS) do swojej odpowiedzi lub skopiuj adres IP klienta do nowego nagłówka HTTP, aby był przekazywany do źródła z żądaniem.
  • Autoryzacja dostępu: Zaimplementuj kontrolę dostępu i autoryzację do treści dostarczanych przez CloudFront, tworząc i weryfikując tokeny generowane przez użytkowników, takie jak tokeny HMAC lub tokeny sieciowe JSON (JWT), aby zezwalać na żądania/odrzucać żądania.

Aby zapewnić wydajność i skalę wymaganą przez nowoczesne aplikacje, CloudFront Functions wykorzystuje nowy model izolacji oparty na procesach zamiast izolacji opartej na maszynach wirtualnych (VM), tak jak jest to używane przez AWS Lambda i Lambda@Edge. Aby to zrobić, AWS wymusił pewne ograniczenia, takie jak unikanie dostępu do sieci i systemu plików.

Ponadto funkcje działają krócej niż jedną milisekundę. W ten sposób mogą obsługiwać miliony żądań na sekundę, zapewniając jednocześnie doskonałą wydajność przy każdym wykonaniu funkcji. Funkcje praktycznie nie wpływają na ogólną wydajność sieci dostarczania treści (CDN).

Podobnie jak Lambda@Edge, CloudFront Functions uruchamia Twój kod w odpowiedzi na zdarzenia generowane przez CloudFront. Mówiąc dokładniej, funkcje CloudFront mogą być uruchamiane po tym, jak CloudFront otrzyma żądanie od klienta (viewer request) i zanim CloudFront przekaże odpowiedź do klienta (viewer response).

Lambda@Edge można również wyzwolić, zanim CloudFront przekaże żądanie do źrodła (origin request) i po tym, jak CloudFront otrzyma odpowiedź od źródła (origin request). Możesz używać CloudFront Functions i Lambda@Edge razem, w zależności od tego, czy musisz manipulować treścią przed, czy po buforowaniu.

CloudFront_Functions

Jeśli potrzebujesz niektórych możliwości Lambda@Edge, które nie są dostępne w CloudFront Functions, takich jak dostęp do sieci lub dłuższy czas wykonania, nadal możesz używać Lambda@Edge przed i po buforowaniu treści przez CloudFront.

CloudFront_Functions

Aby pomóc Ci zrozumieć różnicę między CloudFront Functions i Lambda@Edge, oto krótkie porównanie:

 

 

Funkcje CloudFront

Lambda@Edge

Wspierane środowiska

JavaScript
(zgodny z ECMAScript 5.1)

Node.js, Python

Miejsce wykonania

218+ Lokalizacji CloudFront
Edge

13 Lokalizacji CloudFront
Regional Edge Cache

Obsługiwane triggery CloudFront

Viewer request
Viewer response

Viewer request
Viewer response
Origin request
Origin response

Maksymalny czas realizacji

Mniej niż 1 milisekunda

5 sekund (viewer triggers)
30 sekund (origin triggers)

Maksymalna pamięć

2MB

128MB (viewer triggers)
10GB (origin triggers)

Całkowity rozmiar pakietu

10 KB

1 MB (viewer triggers)
50 MB (origin triggers)

Dostęp do sieci

Nie

Tak

Dostęp do systemu plików

Nie

Tak

Dostęp do treści żądania

Nie

Tak

Cena

Dostępny poziom bezpłatny;

opłata za żądanie

Brak darmowego poziomu; opłata za żądanie i czas trwania funkcji

 

 

Zobaczmy, jak to działa w praktyce.

Korzystanie z funkcji CloudFront z konsoli

Chcemy dostosować zawartość strony internetowej w zależności od kraju pochodzenia widzów. Aby to zrobić, używamy dystrybucji CloudFront, którą utworzyliśmy przy użyciu bucketu S3 jako źródła. Następnie tworzymy zasadę pamięci podręcznej, aby uwzględnić CloudFront-Viewer-Country (zawierający dwuliterowy kod kraju przeglądarki) w kluczu pamięci podręcznej. Funkcje CloudFront mogą wyświetlać nagłówki wygenerowane przez CloudFront (takie jak nagłówki geolokalizacji CloudFront lub nagłówki wykrywania urządzeń) tylko wtedy, gdy są one uwzględnione w zasadach pochodzenia lub zasadach kluczy pamięci podręcznej.

W konsoli CloudFront wybieramy Functions na lewym pasku, a następnie Create function. Nadajemy funkcji nazwę i klikamy Continue.

 

CloudFront_Functions

Stąd możemy śledzić cykl życia funkcji, wykonując następujące kroki:

  1. Zbudować funkcję, dostarczając kod.
  2. Przetestować funkcję za pomocą przykładowych danych.
  3. Opublikować funkcję od etapu rozwoju do etapu na żywo.
  4. Połączyć funkcję z co najmniej jedną dystrybucją CloudFront

CloudFront_Functions

  1. W karcie Build mamy dostęp do dwóch etapów dla każdej funkcji: Developmentdla testów i Live, który może być używany przez jedną lub więcej dystrybucji CloudFront. Po wybraniu etapu rozwoju wpisujemy kod funkcji i klikamy Save:

 

 

JavaScript

function handler(event) {

  var request = event.request;

  var supported_countries = ['de', 'it', 'fr'];

  if (request.uri.substr(3,1) != '/') {

    var headers = request.headers;

    var newUri;

    if (headers['cloudfront-viewer-country']) {

      var countryCode = headers['cloudfront-viewer-country'].value.toLowerCase();

      if (supported_countries.includes(countryCode)) {

        newUri = '/' + countryCode + request.uri;

      }

    }

    if (newUri === undefined) {

      var defaultCountryCode = 'en';

      newUri = '/' + defaultCountryCode + request.uri;

    }

    var response = {

      statusCode: 302,

      statusDescription: 'Found',

      headers: {

        "location": { "value": newUri }

      }

    }

    return response;

  }

  return request;

}

 

Funkcja sprawdza zawartość nagłówka CloudFront-Viewer-Country ustawionego przez CloudFront. Jeśli zawiera jeden z obsługiwanych krajów, a adres URL nie zawiera jeszcze prefiksu kraju, dodaje kraj na początku ścieżki adresu URL. W przeciwnym razie przepuszcza żądanie bez zmian.

  1. Na karcie Test wybieramy typ zdarzenia (Viewer Request), Stage (na razie Development) i przykładowe zdarzenie.

cloudfront-functions

Poniżej możemy dostosować zdarzenie Input, wybierając metodę HTTP, a następnie edytując ścieżkę adresu URL i opcjonalnie IP klienta do użycia. Możemy również dodać niestandardowe nagłówki, pliki cookie lub ciągi zapytań. W naszym przypadku zostawiamy wszystkie wartości domyślne i dodajemy nagłówek CloudFront-Viewer-Country z wartością FR (dla Francji). Opcjonalnie, zamiast korzystać z edytora wizualnego, możemy dostosować zdarzenie wejściowe, edytując dane JSON, które są przekazywane do funkcji.

cloudfront-functions

Klikamy przycisk Test i patrzymy na Output. Zgodnie z oczekiwaniami, żądanie jest przekierowywane (kod stanu HTTP 302). W zakładce Response headers widzimy, że lokalizacja, do której przekierowywane jest żądanie, zaczyna się od /fr/ w celu zapewnienia niestandardowej treści dla użytkowników z Francji. Jeśli coś nie idzie zgodnie z oczekiwaniami w testach, możemy spojrzeć na zakładkę Function Logs. Możemy również użyć console.log() w kodzie, aby dodać więcej informacji  dotyczących debugowania.

cloudfront-functions

W zakładce Output, tuż nad stanem HTTP, widzimy wykorzystanie Compute utilization dla tego wykonania. Wykorzystanie obliczeń to liczba z zakresu od 0 do 100, która wskazuje ilość czasu, jaki zajęła funkcja, jako procent maksymalnego dozwolonego czasu. W tym przypadku wykorzystanie obliczeniowe równe 21 oznacza, że funkcja zakończyła się w 21% maksymalnego dozwolonego czasu.

  1. Wykonujemy więcej testów przy użyciu różnych konfiguracji adresu URL i nagłówków, a następnie przechodzimy do zakładki Publish, aby skopiować funkcję z etapu development do etapu live. Teraz funkcja jest gotowa do powiązania z istniejącą dystrybucją.

Cloudfront-functions

  1. W karcie Associate wybieramy Distribution, Event type (Viewer Request or Viewer Response) oraz Cache behavior(mamy tylko domyślne (*) zachowanie pamięci podręcznej dla dystrybucji). Klikamy Add association i potwierdzamy w oknie dialogowym.

cloudfront-functions

Teraz widzimy skojarzenie funkcji na dole zakładki Associate.

cloudfront-functions

Aby przetestować tę konfigurację z dwóch różnych lokalizacji, uruchamiamy dwie instancje Amazon Elastic Compute Cloud (EC2), jedną w regionie US East (N. Virginia)  i jedną w regionie Europa (Paryż). Łączymy się za pomocą SSH i używamy cURL, aby pobrać obiekt z dystrybucji CloudFront. Wcześniej przesłaliśmy dwa obiekty do bucketu S3, który jest używany jako źródło dystrybucji: jeden dla klientów z Francji, używając prefiksu fr/ i jeden dla klientów spoza obsługiwanego kraju, używając en/ prefiks.

Wymieniamy dwa obiekty za pomocą AWS Command Line Interface (CLI):

$ aws s3 ls --recursive s3://BUCKET

2021-04-01 13:54:20         13 en/doc.txt

2021-04-01 13:54:20          8 fr/doc.txt

 

W instancji EC2 w regionie US East (N. Virginia) uruchamiamy to polecenie, aby pobrać obiekt:

[us-east-1]$ curl -L https://d2wj2l15gt32vo.cloudfront.net/doc.txt

Good morning

 

Następnie wykonujemy to samo polecenie w Regionie Europa (Paryż):

[eu-west-3]$ curl -L https://d2wj2l15gt32vo.cloudfront.net/doc.txt

Bonjour

 

Zgodnie z oczekiwaniami otrzymujemy różne wyniki z tego samego adresu URL. Używamy opcji -L, aby cURL podążał za otrzymanym przekierowaniem. W ten sposób każde polecenie wykonuje dwa żądania HTTP: pierwsze żądanie otrzymuje przekierowanie HTTP z funkcji CloudFront, drugie żądanie następuje po przekierowaniu i nie jest modyfikowane przez funkcję, ponieważ zawiera niestandardową ścieżkę w adresie URL (/en/lub /fr/).

 

Aby zobaczyć rzeczywistą lokalizację przekierowania i wszystkie nagłówki odpowiedzi HTTP, używamy cURL z opcją -i. To są nagłówki odpowiedzi dla instancji EC2 działającej w USA; funkcja jest wykonywana w lokalizacji brzegowej w Wirginii:

[us-east-1]$ curl -i https://d2wj2l15gt32vo.cloudfront.net/doc.txt

HTTP/2 302

server: CloudFront

date: Thu, 01 Apr 2021 14:39:31 GMT

content-length: 0

location: /en/doc.txt

x-cache: FunctionGeneratedResponse from cloudfront

via: 1.1 cb0868a0a661911b98247aaff77bc898.cloudfront.net (CloudFront)

x-amz-cf-pop: IAD50-C2

x-amz-cf-id: TuaLKKg3YvLKN85fzd2qfcx9jOlfMQrWazpOVmN7NgfmmcXc1wzjmA==

 

A to są nagłówki odpowiedzi dla instancji EC2 działającej we Francji; tym razem funkcja jest wykonywana w lokalizacji brzegowej w pobliżu Paryża:

[eu-west-3]$ curl -i https://d2wj2l15gt32vo.cloudfront.net/doc.txt

HTTP/2 302

server: CloudFront

date: Thu, 01 Apr 2021 14:39:26 GMT

content-length: 0

location: /fr/doc.txt

x-cache: FunctionGeneratedResponse from cloudfront

via: 1.1 6fa25eadb94abd73b5efc56a89b2d829.cloudfront.net (CloudFront)

x-amz-cf-pop: CDG53-C1

x-amz-cf-id: jzWcbccJiTDRj22TGwsn_

 

Dostępność i ceny

Funkcje CloudFront Functions są już dostępne i możesz ich używać z nowymi i istniejącymi dystrybucjami. Funkcji CloudFront można używać z konsolą AWS Management Console, interfejsem AWS Command Line Interface (CLI), pakietami AWS SDKs oraz AWS CloudFormation. Dzięki CloudFront Functions płacisz według liczby wywołań. Możesz rozpocząć korzystanie z CloudFront Functions za darmo w ramach poziomu bezpłatnego użytkowania AWS Free Usage Tier. Aby uzyskać więcej informacji, zobacz stronę z cennkiem CloudFront.

AWS for the Edge

Funkcje sieci brzegowej Amazon CloudFront i AWS są częścią oferty AWS for the Edge. Usługi brzegowe AWS poprawiają wydajność, przenosząc moc obliczeniową, przetwarzanie danych i pamięć masową bliżej urządzeń użytkowników końcowych. Obejmuje to wdrażanie usług zarządzanych przez AWS, interfejsów API i narzędzi w lokalizacjach poza centrami danych AWS, a nawet w infrastrukturze i urządzeniach klientów.

AWS oferuje spójne doświadczenie i portfolio możliwości od brzegu po chmurę. Korzystając z AWS, masz dostęp do najszerszych i najgłębszych możliwości zastosowań brzegowych, takich jak sieci brzegowe, architektury hybrydowe, podłączone urządzenia, 5G i wielodostępowe przetwarzanie brzegowe.

Zacznij korzystać z CloudFront Functions już dziś, aby dodać niestandardową logikę na krawędzi do swoich aplikacji.

 

źródło: AWS

Case Studies
Referencje

Firma Hostersi pozwoliła nam osadzić ogólne zagadnienia programu Well Architected Framework w kontekście naszej firmy. Oszczędziło nam to wiele czasu i pozwoliło znaleźć lepiej dopasowane rozwiązania do specyfiki naszego biznesu. WAF był świetnym katalizatorem do wprowadzenie szeregu zmian w obszarze niezawodności, szybkości i bezpieczeństwa edrone. 

Piotr Stachowicz
CTO
W skrócie o nas
Specjalizujemy się w dostarczaniu rozwiązań IT w obszarach projektowania infrastruktury serwerowej, wdrażania chmury obliczeniowej, opieki administracyjnej i bezpieczeństwa danych.