Amazon S3 Object Lambda - Użycie własnego kodu do przetwarzania danych w momencie ich pobierania z S3

14 kwietnia 2021

Kiedy przechowujesz dane w usłudze Amazon Simple Storage Service (S3), możesz je łatwo udostępniać do użytku przez wiele aplikacji. Jednak każda aplikacja ma swoje własne wymagania i może wymagać innego widoku danych.

Na przykład zbiór danych utworzony przez aplikację e-commerce może zawierać dane osobowe (PII), które nie są potrzebne, gdy te same dane są przetwarzane do celów analitycznych i powinny zostać zredagowane. Z drugiej strony, jeśli ten sam zestaw danych jest używany do kampanii marketingowej, może być konieczne wzbogacenie danych o dodatkowe szczegóły, takie jak informacje z bazy danych lojalności klientów.

Aby zapewnić różne widoki danych wielu aplikacjom, obecnie dostępne są dwie opcje. Tworzysz, przechowujesz i utrzymujesz dodatkowe pochodne kopie danych, tak aby każda aplikacja miała własny, niestandardowy zestaw danych, lub tworzysz infrastrukturę i zarządzasz nią jako warstwa proxy przed S3 w celu przechwytywania i przetwarzania danych zgodnie z żądaniem. Obie opcje zwiększają złożoność i koszty, więc zespół S3 postanowił stworzyć lepsze rozwiązanie.

Niedawno AWS ogłosił dostępność funkcji S3 Object Lambda, nowej możliwości, która umożliwia dodanie własnego kodu do przetwarzania danych pobranych z S3 przed zwróceniem ich do aplikacji. S3 Object Lambda współpracuje z istniejącymi aplikacjami i wykorzystuje funkcje AWS Lambda do automatycznego przetwarzania i przekształcania danych podczas ich pobierania z S3. Funkcja Lambda jest wywoływana inline ze standardowym żądaniem  S3 GET request, więc nie musisz zmieniać kodu aplikacji.

W ten sposób możesz łatwo przedstawić wiele widoków z tego samego zbioru danych i możesz zaktualizować funkcje Lambda, aby zmodyfikować te widoki w dowolnym momencie.

Amazon S3 Object Lambda - Użycie własnego kodu do przetwarzania danych w momencie ich pobierania z S3

Istnieje wiele przypadków użycia, które można uprościć dzięki temu podejściu, na przykład:

  • Redagowanie danych osobowych na potrzeby środowisk analitycznych lub nieprodukcyjnych.
  • Konwersja różnych formatów danych, np. konwersja XML do JSON.
  • Uzupełnianie danych o informacje z innych usług lub baz danych.
  • Kompresowanie lub dekompresowanie plików podczas ich pobierania.
  • Zmiana rozmiaru i dodawanie znaków wodnych obrazów w locie przy użyciu szczegółowych informacji, takich jak użytkownik, który zażądał obiektu.
  • Wdrażanie niestandardowych reguł autoryzacji dostępu do danych.

Możesz zacząć korzystać z S3 Object Lambda, wykonując kilka prostych kroków:

  1. Utwórz funkcję Lambda, aby przekształcić dane dla twojego przypadku użycia.
  2. Utwórz punkt S3 Object Lambda Access Point z konsoli S3 Management Console.
  3. Wybierz funkcję Lambda, którą utworzyłeś powyżej.
  4. Zapewnij pomocniczy punkt dostępu S3 Access Point, aby umożliwić dostęp do oryginalnego obiektu.
  5. Zaktualizuj konfigurację aplikacji, aby używać nowego punktu dostępowego S3 Object Lambda Access Point do pobierania danych z S3.

Aby lepiej zrozumieć, jak działa S3 Object Lambda, zastosujmy to w praktyce.

Jak utworzyć funkcje Lambda dla S3 Object Lambda

Aby utworzyć funkcję, zaczniemy od spojrzenia na składnię zdarzenia wejściowego, które funkcja Lambda otrzymuje z S3 Object Lambda:

JSON

{

    "xAmzRequestId": "1a5ed718-5f53-471d-b6fe-5cf62d88d02a",

    "getObjectContext": {

        "inputS3Url": "https://myap-123412341234.s3-accesspoint.us-east-1.amazonaws.com/s3.txt?X-Amz-Security-Token=...",

        "outputRoute": "io-iad-cell001",

        "outputToken": "..."

    },

    "configuration": {

        "accessPointArn": "arn:aws:s3-object-lambda:us-east-1:123412341234:accesspoint/myolap",

        "supportingAccessPointArn": "arn:aws:s3:us-east-1:123412341234:accesspoint/myap",

        "payload": "test"

    },

    "userRequest": {

        "url": "/s3.txt",

        "headers": {

            "Host": "myolap-123412341234.s3-object-lambda.us-east-1.amazonaws.com",

            "Accept-Encoding": "identity",

            "X-Amz-Content-SHA256": "e3b0c44297fc1c149afbf4c8995fb92427ae41e4649b934ca495991b7852b855"

        }

    },

    "userIdentity": {

        "type": "IAMUser",

        "principalId": "...",

        "arn": "arn:aws:iam::123412341234:user/myuser",

        "accountId": "123412341234",

        "accessKeyId": "..."

    },

    "protocolVersion": "1.00"

}

 

Właściwość getObjectContext zawiera niektóre z najbardziej przydatnych informacji dotyczących funkcji Lambda:

  • inputS3Url to wstępnie podpisany adres URL, którego funkcja może użyć do pobrania oryginalnego obiektu z obsługującego go Access Pointu. W ten sposób funkcja Lambda nie musi mieć uprawnień do odczytu S3, aby pobrać oryginalny obiekt i może uzyskać dostęp tylko do obiektu przetwarzanego przez każde wywołanie.
  • outputRoute i outputToken to dwa parametry używane do odesłania zmodyfikowanego obiektu za pomocą nowego WriteGetObjectResponse API.

 

Właściwość configuration zawiera Amazon Resource Name (ARN) punktu dostępowego Object Lambda i obsługującego go punktu dostępowego.

Właściwość userRequest zawiera więcej informacji o pierwotnym żądaniu, takich jak ścieżka w adresie URL i nagłówki HTTP.

Na koniec sekcja userIdentity zwraca szczegółowe informacje o tym, kto złożył pierwotne żądanie i może służyć do dostosowywania dostępu do danych.

 

Teraz, gdy znamy składnię zdarzenia, możemy utworzyć funkcję Lambda. Aby uprościć sprawę, oto funkcja napisana w Pythonie, która zmienia cały tekst w oryginalnym obiekcie na wielkie litery:

Python

import boto3

import requests

 

def lambda_handler(event, context):

    print(event)

 

    object_get_context = event["getObjectContext"]

    request_route = object_get_context["outputRoute"]

    request_token = object_get_context["outputToken"]

    s3_url = object_get_context["inputS3Url"]

 

    # Get object from S3

    response = requests.get(s3_url)

    original_object = response.content.decode('utf-8')

 

    # Transform object

    transformed_object = original_object.upper()

 

    # Write object back to S3 Object Lambda

    s3 = boto3.client('s3')

    s3.write_get_object_response(

        Body=transformed_object,

        RequestRoute=request_route,

        RequestToken=request_token)

 

    return {'status_code': 200}

 

Patrząc na kod funkcji, istnieją trzy główne sekcje:

  • Najpierw używamy właściwości inputS3Url zdarzenia wejściowego, aby pobrać oryginalny obiekt. Ponieważ wartość jest podpisanym adresem URL, funkcja nie potrzebuje uprawnień do odczytu z S3.
  • Następnie przekształcamy tekst tak, aby był pisany wielkimi literami. Aby dostosować zachowanie funkcji do swojego przypadku użycia, musisz zmienić tę część. Na przykład, aby wykryć i zredagować informacje umożliwiające identyfikację osoby (PII), możesz użyć Amazon Comprehend do zlokalizowania jednostek umożliwiających identyfikację (locate PII entities) za pomocą interfejsu API DetectPiiEntities i zastąpienia ich gwiazdkami lub opisem zredagowanego typu jednostki.
  • Na koniec używamy nowego API WriteGetObjectResponse, aby wysłać wynik transformacji z powrotem do S3 Object Lambda. W ten sposób przekształcony obiekt może być znacznie większy niż maksymalny rozmiar odpowiedzi zwracanej przez funkcję Lambda. W przypadku większych obiektów, API WriteGetObjectResponse obsługuje kodowanie transferu typu chunked w celu zaimplementowania przesyłania strumieniowego danych. Funkcja Lambda musi tylko zwrócić kod stanu (w tym przypadku 200 OK), ewentualne błędy i opcjonalnie dostosować metadane zwracanego obiektu zgodnie z opisem S3 GetObject API.

 

Pakujemy funkcję i jej zależności, w tym zaktualizowaną wersję AWS SDK for Python (boto3) implementującą nową metodę write_get_object_response i wgrywamy ją do Lambda. Należy zauważyć, że maksymalny czas trwania funkcji Lambda używanej przez S3 Object Lambda wynosi 60 sekund i że funkcja ta wymaga uprawnień AWS Identity and Access Management (IAM), aby wywołać API WriteGetObjectResponse.

Jak utworzyć punkt dostępowy Lambda obiektu S3 z poziomu konsoli

W konsoli S3 console tworzymy punkt dostępu S3 na jednym z bucketów S3:

Jak utworzyć punkt dostępowy Lambda obiektu S3 z poziomu konsoli

Następnie tworzymy S3 Object Lambda Access Point, używając pomocniczego Access Pointu, który właśnie utworzyliśmy. Funkcja Lambda będzie używać obsługującego Access Pointa do pobierania oryginalnych obiektów.

Funkcja Lambda będzie używać obsługującego Access Pointa do pobierania oryginalnych obiektów.

Podczas konfigurowania punktu dostępowego S3 Object Lambda Access Point, jak pokazano poniżej, wybieramy najnowszą wersję funkcji Lambda, którą utworzyliśmy powyżej. Opcjonalnie możemy włączyć obsługę żądań korzystających z zakresu byte range lub numerów part numbers. Na razie zostawiamy je wyłączone. Aby zrozumieć, jak używać zakresu bajtów i numerów części z S3 Object Lambda, zapoznaj się z dokumentacją.

Lambda function

Podczas konfigurowania S3 Object Lambda Access Point, możemy ustawić string jako payload, który jest przekazywany do funkcji Lambda we wszystkich wywołaniach pochodzących z tego Access Pointu, jak widać we właściwości configuration przykładowego zdarzenia, które opisaliśmy wcześniej. W ten sposób możemy skonfigurować tę samą funkcję Lambda dla wielu punktów dostępowych S3 Object Lambda i użyć wartości payload  do dostosowania zachowania każdego z nich.

Payload

Wreszcie możemy ustawić politykę, podobną do tego, co możemy zrobić z normalnymi punktami dostępowymi S3, aby zapewnić dostęp do obiektów dostępnych za pośrednictwem tego Object Lambda Access Point. Na razie polityka pozostawiamy pustą. Następnie zostawiamy domyślną opcję blokowania publicznego dostępu i tworzenia Object Lambda Access Point.

Teraz, gdy punkt S3 Object Lambda Access Point jest gotowy, zobaczmy, jak możemy go użyć.

 

Jak użyć S3 Object Lambda Access Point

W konsoli S3, wybieramy nowo utworzony Object Lambda Access Point. We właściwościach kopiujemy ARN, aby był później dostępny.

Jak użyć S3 Object Lambda Access Point

Za pomocą AWS Command Line Interface (CLI) przesyłamy plik tekstowy zawierający kilka zdań do bucketu S3 za S3 Object Lambda Access Point:

aws cp s3.txt s3://danilop-data/

Używanie S3 Object Lambda z istniejącymi aplikacjami jest bardzo proste. Musimy tylko zamienić bucket S3 na ARN punktu dostępowego S3 Object Lambda i zaktualizować AWS SDK, aby zaakceptować nową składnię przy użyciu S3 Object Lambda ARN.

Na przykład, poniżej mamy skrypt Pythona, który pobiera plik tekstowy, który właśnie załadowaliśmy: najpierw prosto z bucketu S3, a następnie z S3 Object Lambda Access Point. Jedyną różnicą między dwoma pobraniami jest wartość parametru Bucket.

Python

import boto3

s3 = boto3.client('s3')

print('Original object from the S3 bucket:')

original = s3.get_object(

  Bucket='danilop-data',

  Key='s3.txt')

print(original['Body'].read().decode('utf-8'))

print('Object processed by S3 Object Lambda:')

transformed = s3.get_object(

  Bucket='arn:aws:s3-object-lambda:us-east-1:123412341234:accesspoint/myolap',

  Key='s3.txt')

print(transformed['Body'].read().decode('utf-8'))Python

 

Uruchamiamy skrypt:

python3 read_original_and_transformed_object.py

 

A oto wynik jaki otrzymujemy:

Original object on S3:
Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance. This means customers of all sizes and industries can use it to store and protect any amount of data for a range of use cases, such as data lakes, websites, mobile applications, backup and restore, archive, enterprise applications, IoT devices, and big data analytics.

Object processed by S3 Object Lambda:
AMAZON SIMPLE STORAGE SERVICE (AMAZON S3) IS AN OBJECT STORAGE SERVICE THAT OFFERS INDUSTRY-LEADING SCALABILITY, DATA AVAILABILITY, SECURITY, AND PERFORMANCE. THIS MEANS CUSTOMERS OF ALL SIZES AND INDUSTRIES CAN USE IT TO STORE AND PROTECT ANY AMOUNT OF DATA FOR A RANGE OF USE CASES, SUCH AS DATA LAKES, WEBSITES, MOBILE APPLICATIONS, BACKUP AND RESTORE, ARCHIVE, ENTERPRISE APPLICATIONS, IOT DEVICES, AND BIG DATA ANALYTICS.

 

Pierwsze dane wyjściowe są pobierane bezpośrednio z kontenera źródłowego i widzimy oryginalną zawartość zgodnie z oczekiwaniami. Za drugim razem obiekt jest przetwarzany przez funkcję Lambda w trakcie pobierania i w rezultacie cały tekst jest pisany wielkimi literami.

Więcej przypadków użycia dla S3 Object Lambda

Podczas pobierania obiektu za pomocą S3 Object Lambda nie ma potrzeby, aby obiekt o tej samej nazwie istniał w buckecie S3. Funkcja Lambda może wykorzystać informacje zawarte w nazwie pliku lub w nagłówkach HTTP do wygenerowania niestandardowego obiektu.

Na przykład, jeśli poprosisz o użycie S3 Object Lambda Access Point dla obrazu o nazwie sunset_600x400.jpg, funkcja Lambda może wyszukać obraz o nazwie sunset.jpg i zmienić jego rozmiar, aby dopasować maksymalną szerokość i wysokość zgodnie z opisem w nazwie pliku. W takim przypadku funkcja Lambda wymagałaby uprawnień dostępu do odczytu oryginalnego obrazu, ponieważ klucz obiektu różni się od tego, który został użyty w podpisanym adresie URL.

Innym interesującym przypadkiem użycia byłoby pobieranie dokumentów JSON lub CSV, takich jak order.json lub items.csv, które są generowane w locie na podstawie zawartości bazy danych. Metadane w nagłówkach HTTP żądania mogą służyć do przekazywania orderId.

Oto krótki film opisujący, jak działa S3 Object Lambda i jak z niej korzystać:

 

Dostępność i ceny

S3 Object Lambda jest obecnie dostępna we wszystkich regionach AWS z wyjątkiem regionu Azji i Pacyfiku (Osaka), AWS GovCloud (USA-Wschód), AWS GovCloud (Zachód USA), Chin (Pekin) i Chin (Ningxia). Możesz używać S3 Object Lambda z AWS Management Console, AWS Command Line Interface (CLI) i AWS SDK. Obecnie polecenia AWS CLI high-level S3, takie jak aws s3 cp, nie obsługują obiektów z punktów S3 Object Lambda Access Points, ale można używać poleceń niskopoziomowego interfejsu API S3, takich jak aws s3api get-object.

 

Dzięki S3 Object Lambda płacisz za obliczenia AWS Lambda i żądania wymagane do przetwarzania danych, oraz za dane S3, które Lambda zwraca do Twojej aplikacji. Płacisz również za żądania S3, które są wywoływane przez funkcję Lambda. Więcej informacji o cenach można znaleźć na stronie z cenami Amazon S3 pricing page.

Ta nowa funkcja znacznie ułatwia udostępnianie i konwertowanie danych w wielu aplikacjach.

ź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.