Поиск по сайту:

Как использовать AWS Object Lambda для преобразования объектов S3 по запросу


Object Lambda позволяет поместить функцию Lambda перед объектами S3, что позволяет преобразовывать их по запросу с помощью вашего собственного пользовательского кода. Поскольку он автоматически запускается на Lambda, вам не нужно беспокоиться о запуске собственного прокси-слоя.

Что такое объектная лямбда?

Object Lambda в основном заменяет API перед S3. Раньше вам приходилось настраивать прокси-уровень в собственной инфраструктуре для обработки трансформирующихся объектов по запросу. Это добавляет сложности, поэтому AWS добавила лучшее решение.

Вместо прямого доступа к объектам вы будете делать это через точку доступа Object Lambda. Когда вы делаете запрос GET для файла в корзине S3, функция Lambda для этой точки доступа будет автоматически вызвана, разрешен доступ к исходному объекту и возврат преобразованного объекта обратно в приложение.

Использование для этого может быть простым, например, редактирование информации или преобразование JSON в XML, но, поскольку это ваш собственный код, вы можете делать все, что захотите. Вы можете, например, выполнить поиск в базе данных и вернуть преобразованный объект с новыми данными или сделать запросы к внешним API.

У вас может быть несколько точек доступа для каждой корзины, каждая из которых может представлять несколько «представлений» базовых данных. Чтобы использовать разные точки доступа, вам не нужно будет обновлять какой-либо клиентский код. Просто измените имя корзины на ARN точки доступа Object Lambda.

s3.get_object( 
    Bucket='arn:aws:s3-object-lambda:us-east-1:123412341234:accesspoint/myolap', 
    Key='s3.txt' )

Вам также не нужно обращаться к исходному объекту по точному имени. Например, ваше приложение может запросить picture_1920x1080.jpg, которое найдет picture.jpg и изменит его размер до заданных размеров. В этом случае функции Lambda потребуются дополнительные разрешения для доступа к содержимому корзины.

Конечно, вам нужно будет платить за все время, потраченное на выполнение функций Lambda. Если вы запускаете множество функций через точку доступа, обращенную к пользователю, это может начать складываться. Если ваши преобразования являются статическими, вы можете рассмотреть возможность кэширования объектов в отдельной корзине S3. Например, если у вас есть функция, которая применяет фильтры/сжатие к изображению, вы можете кэшировать результаты, а не перестраивать их при каждом запросе. Однако для вещей, зависящих от внешнего состояния, это невозможно.

Использование объектной лямбды

Перейдите к консоли управления S3, чтобы начать. За каждой точкой доступа Object Lambda требуется обычная точка доступа. Вам нужно будет создать это из «Точки доступа»> «Создать» на боковой панели.

Введите имя и выберите корзину, и обязательно выберите «Интернет», если эта корзина не ограничена одним VPC. После создания скопируйте ARN для точки доступа.

Создайте объектную лямбда-точку доступа:

Дайте ему имя и вставьте его в ARN точки доступа, и консоль должна отобразить имя базовой корзины.

На этом этапе вам нужно выбрать лямбда-функцию. Если у вас есть готовый, вы можете ввести ARN или выбрать его из списка. В противном случае вам нужно будет перейти в консоль управления Lambda, чтобы создать ее.

На этом этапе код зависит от вас, хотя AWS предоставляет следующий пример, который берет исходный объект и преобразует его в верхний регистр. Независимо от того, какой язык вы в конечном итоге используете, вам нужно будет получить контекст события, сделать запрос к S3, используя URL-адрес, преобразовать объект, а затем написать ответ с помощью нового API WriteGetObjectResponse, возвращая впоследствии код состояния HTTP.

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}

Объект события, который получает Lambda, будет выглядеть примерно так:

{
    "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"
}

Здесь есть две важные части информации: раздел userRequest, который содержит информацию об исходном запросе, такую как заголовки URL и HTTP, и раздел userIdentity , который можно использовать персонализировать ответ на основе пользователя IAM.