S3 Object Lambdaを試してみた

AWS

背景

S3 Object Lambdaを全く触ったことがなく、どんなサービスなのかもあまり知らなかったので試してみる。

S3とLambdaはよく利用するので、本サービスを認知していると選択肢の幅が広がりそうだと考えやってみた。

S3 Object Lambdaとは?

AWSサービスページによると下記のとおり。

S3 GET、HEAD および LIST リクエストに独自のコードを追加して、データがアプリケーションに返されるときにデータを変更および処理します

試してみた

このドキュメントをもとにやってみる。

ステップ3以降がメインになる。

ステップ1. S3バケットを作成

コンソールからデフォルト設定で作成。

ステップ2. ファイルをアップロード

後続ステップでテキストファイルを大文字に変換して取得できるようにする。

tutorial.txt

Amazon S3 Object Lambda Tutorial:
You can add your own code to process data retrieved from S3 before 
returning it to an application.

ステップ3. S3アクセスポイントの作成

S3 Object Lambdaアクセスポイントを使用して元データにアクセスし変換するには、S3アクセスポイントを作成し、S3バケットに関連付けをする。

ネットワークオリジンは「インターネット」を選択。

それ以外はデフォルトでOK。

ステップ4. Lambda関数の作成

S3 Object Lambdaアクセスポイントで使用するLambda関数を作成。

詳細な手順はこちらを参照。

Lambdaが受け取るイベントは、イベントコンテキストの形式と使用法を確認。

transform.py

import boto3
import requests
from botocore.config import Config

# This function capitalizes all text in the original object
def lambda_handler(event, context):
    object_context = event["getObjectContext"]
    # Get the presigned URL to fetch the requested original object 
    # from S3
    s3_url = object_context["inputS3Url"]
    # Extract the route and request token from the input context
    request_route = object_context["outputRoute"]
    request_token = object_context["outputToken"]
    
    # Get the original S3 object using the presigned URL
    response = requests.get(s3_url)
    original_object = response.content.decode("utf-8")

    # Transform all text in the original object to uppercase
    # You can replace it with your custom code based on your use case
    transformed_object = original_object.upper()

    # Write object back to S3 Object Lambda
    s3 = boto3.client('s3', config=Config(signature_version='s3v4'))
    # The WriteGetObjectResponse API sends the transformed data
    # back to S3 Object Lambda and then to the user
    s3.write_get_object_response(
        Body=transformed_object,
        RequestRoute=request_route,
        RequestToken=request_token)

    # Exit the Lambda function: return the status code  
    return {'status_code': 200}

ソースコードの要点

  • getObjectContext からコンテキスト取得
  • inputS3Url は署名付きURLなので、APIリクエストでオブジェクト取得
  • write_get_object_response でObject Lambda アクセス ポイントにデータを提供

ステップ5. Lambda 関数の実行ロールのIAM ポリシーを設定

Lambdaの実行ロールに AmazonS3ObjectLambdaExecutionRolePolicy を追加する。

ステップ6. Object Lambda アクセスポイントの作成

S3 Object Lambda アクセスポイントを作成および設定するときは、Lambda が使用するカスタムパラメーターとして JSON 形式のイベントコンテキストを呼び出し、提供する Lambda 関数を指定する必要があります。

  • ステップ3のアクセスポイントを選択
  • S3 APIは GETObjectを選択
  • ステップ4のLambdaを選択

ステップ 7. 変換されたデータを表示

これまでのステップでデータ変換の準備はOK。

今回のS3 Object Lambda はオブジェクト内のすべてのテキストを大文字に変換する。

S3 Object Lambda アクセスポイントの変換済みデータの表示

大文字に変換されたテキストが表示された。

(初回読み込み時は、しっかりとLambdaのコールドスタートを体感できる..)

Python スクリプトを実行して、元のデータと変換されたデータを出力する

ステップ 6 で、S3 からのデータを作成した新しい S3 Object Lambda アクセスポイント ARN を使用してデータを取得します。

pythonスクリプトを記述。

SDKも使えるので便利。

BucketのパラメータにS3 object lambda アクセスポイントのARNを指定するだけでOK。

tutorial_print.py

import boto3
from botocore.config import Config
session = boto3.Session(profile_name="profile-name")
s3 = session.client('s3', config=Config(signature_version='s3v4'))

def getObject(bucket, key):
    objectBody = s3.get_object(Bucket=bucket, Key=key)
    print(objectBody["Body"].read().decode("utf-8"))
    print("\\n")

print('Original object from the S3 bucket:')
# Replace the two input parameters of getObject() below with
# the S3 bucket name that you created in Step 1 and
# the name of the file that you uploaded to the S3 bucket in Step 2
getObject("demo1-2023-11-30-s3-object-lambda",
          "tutorial.txt")

print('Object transformed by S3 Object Lambda:')
# Replace the two input parameters of getObject() below with
# the ARN of your S3 Object Lambda Access Point that you saved earlier and
# the name of the file with the transformed data (which in this case is
# the same as the name of the file that you uploaded to the S3 bucket
# in Step 2)
getObject("arn:aws:s3-object-lambda:ap-northeast-1:111122223333:accesspoint/tutorial-object-lambda-accesspoint",
          "tutorial.txt")

所感

サービスの基本的な使い方は掴めた。

ユースケースに合わせて利用するためには、しっかりドキュメントを読んだり検証をしたりする必要があると感じた。

SDKで変換したS3 Objectにアクセスできるのはシンプルでよいと思った。

S3の「アクセスポイント」と「Object Lambda アクセスポイント」の2つの関係性が複雑だと感じた。また、Lambdaの実装ついても一癖ありそうだと感じた。


おまけ

S3 Object Lambda によって使用される Lambda 関数の最大持続時間は 60 秒

Lambdaのタイムアウトは60秒。

一般的なユースケースは以下。

  • 機密データのマスキング
  • 特定のデータ行のフィルタリング
  • データベースの情報を付与してデータ強化
  • データ形式の変換
  • ダウンロード中のファイルを圧縮、解凍
  • 画像のサイズ変更、ウォーターマーク

IAMポリシーの s3-object-lambda:WriteGetObjectResponseで指定するリソースタイプはobjectlambdaaccesspoint*になる。

arn:${Partition}:s3-object-lambda:${Region}:${Account}:accesspoint/${AccessPointName}
無料相談実施中
AWSを使用したサーバーレスアプリケーションの構築
サーバーレス開発内製化、AWSへの移行等
様々な課題について無料でご相談お受けいたします。
最新情報をチェックしよう!