AWS Lambda PythonからCloudinaryを操作してみた

2020.03.09

画像最適化SaaSのCloudinaryをAWS Lambda Pythonから操作する方法を紹介します。

やってみた

以下の流れで実装します。

  1. Python Cloudinary SDK を Lambda Layer で登録
  2. Lambda 関数を作成

1. Python Cloudinary SDK を AWS Lambda Layer に登録

AWS Lambdaにはレイヤーという概念があり、ライブラリのような依存関係をLambda関数から切り離して登録することが可能です。

Lambda関数内にはロジックのみを記述したいので、CloudinaryのPython SDKをこのレイヤーとして登録します。

ライブラリ群をZIPで固め、lambda::publish-layer-version API で登録します。

$ pip install -t python cloudinary==1.20.0
$ zip -r cloudinary-1.20.0.zip python > /dev/null
$ aws lambda publish-layer-version \
  --layer-name cloudinary \
  --description "cloudinary 1.20.0" \
  --zip-file fileb://cloudinary-1.20.0.zip \
  --compatible-runtimes python3.6 python3.7 python3.8

{
    "Content": {
        "Location": "https://awslambda-eu-cent-1-layers.s3.eu-central-1.amazonaws.com/snapshots/...",
        "CodeSha256": "EOCOZ9ox3tvyQyZ415jzU0C7bstg1NYaPu1UfQV+Iqs=",
        "CodeSize": 653315
    },
    "LayerArn": "arn:aws:lambda:eu-central-1:12345:layer:cloudinary",
    "LayerVersionArn": "arn:aws:lambda:eu-central-1:12345:layer:cloudinary:1",
    "Description": "cloudinary 1.20.0",
    "CreatedDate": "2020-03-05T12:44:54.500+0000",
    "Version": 1,
    "CompatibleRuntimes": [
        "python3.6",
        "python3.7",
        "python3.8"
    ]
}

2. Lambda 関数を作成

Cloudinary に fetch されたキャッシュを削除する Uploader::Destroy API を呼び出してみます。

実質的に、次の過去記事で紹介したスクリプトのLambda関数化です。

Cloudinaryで一度fetchしたオリジン画像を更新する | Developers.IO

cloudinary_destroy.py

import cloudinary
import cloudinary.uploader

cloudinary.config(
  cloud_name = 'XXX',
  api_key = 'XXX',
  api_secret = 'XXX',
  upload_prefix = 'https://api-ap.cloudinary.com'
)

public_id = "https://example.com/dog.png"

def lambda_handler(event, context):
    print(event)
 
    res = cloudinary.uploader.destroy(
        public_id = public_id,
        type = 'fetch',
        invalidate = True)
    print(res)

public_id は実際の構成・呼び出し方式に合わせて調整してください。

ユースケース

Cloudinary API 呼び出しを Lambda 関数化したユースケースを紹介します。

画像を S3 で管理されており、Cloudinary はこの S3 バケットを fetch しているとします。

一度 fetch したデータは Cloudinary の TTL(デフォルトで7日)が過ぎるまでは再 fetch しません。 Cloudinary と S3 間でデータの不整合が発生しないようにするには、S3 オブジェクトの更新をトリガーに Cloudinary のキャッシュをパージする必要があります。

以下の様にすることでリアルタイムパージを実現できます。

  1. パージ処理をLambda関数
  2. CloudTrailでS3のオブジェクトレベル API ロギングを有効化
  3. EventBridgeでS3更新系APIをトリガーに、パージ処理用Lambda関数を呼び出すように設定

参考