TLDR:Lambda関数からの応答に対して新しいキャッシュ動作を作成して、CloudFront 307リダイレクトキャッシュをだます必要があります。
私たちがこれを達成するのにどれほど近いか信じられないでしょう。私たちは最後のステップでひどくこだわっています。
ビジネスケース:
私たちのアプリケーションはS3に画像を保存し、世界中の地理的な速度低下を避けるためにCloudFrontでそれらを提供します。さて、私たちはデザインに本当に柔軟性があり、ChouldFront URLで直接新しい画像寸法をリクエストできるようにしたいと思います!新しい各イメージサイズはオンデマンドで作成され、S3に保存されるため、2回目にリクエストされたときに、S3に存在し、CloudFrontにもキャッシュされるため、非常に迅速に提供されます。
ユーザーが画像chucknorris.jpgをアップロードしたとしましょう。元の画像のみがS3に保存され、次のようにページに表示されます。
//xxxxx.cloudfront.net/chucknorris.jpg
200x200ピクセルのサムネイルを表示する必要があると計算しました。したがって、画像srcをテンプレートに配置します。
//xxxxx.cloudfront.net/chucknorris-200x200.jpg
この新しいサイズが要求されると、Amazon Webサービスは、同じバケット内で、要求されたキーを使用して、その場でサイズを提供する必要があります。これにより、CloudFrontの同じURLに画像が直接読み込まれます。
私はアーキテクチャの概要とAWSでこれを行う方法のワークフローを使って醜い図を作成しました。
Python Lambdaの終了方法は次のとおりです。
return {
'statusCode': '301',
'headers': {'location': redirect_url},
'body': ''
}
問題:
Lambda関数をS3にリダイレクトすると、チャームのように機能します。 CloudFrontにリダイレクトすると、CloudFrontは307(および301、302、303と同様)をキャッシュするため、リダイレクトループに入ります。 Lambda関数がCloudFrontにリダイレクトするとすぐに、CloudFrontはS3から画像をフェッチする代わりにAPI Getaway URLを呼び出します。
CloudFrontのBehaviors
設定タブで新しいキャッシュ動作を作成したいと思います。この動作では、LambdaまたはS3からの応答はキャッシュされません(内部で何が起こっているのか正確にはわかりません)が、この同じサイズ変更されたイメージに対する後続の要求はキャッシュされます。パスパターン-\d+x\d+\..+$
を設定し、Lambda関数のARNをadd "Lambda Function Association"に追加して、イベントタイプOrigin Response
を設定しようとしています。次に、「デフォルトTTL」を0
に設定します。
しかし、いくつかのエラーのために動作を保存できません:
私たちは正しい方向に進んでいますか、それともこの「ラムダ関数関連付け」の考え方はまったく異なりますか?
ようやく解決できました。これは実際には構造的な解決策ではありませんが、必要なことを行います。
まず、マイケルの回答のおかげで、すべてのメディアタイプに一致するパスパターンを使用しました。次に、キャッシュ動作ページは少し誤解を招きやすいものでした。実際、LambdaアソシエーションはLambda @ Edgeを対象としていますが、キャッシュ動作のすべてのツールチップにはこれが表示されていません。表示されるのはLambdaだけです。この特定の問題のために、AWSサービススコープをLambda @ Edgeで拡張したくないので、この機能は役に立ちません。
ソリューションアプローチは次のとおりです。
サポートするメディアタイプごとに1つ、複数のキャッシュ動作を定義しました:
キャッシュ動作ごとに、Default TTL
を0
に設定しました。
そして最も重要な部分:Lambda関数で、S3に配置するときにサイズ変更された画像にCache-Control
ヘッダーを追加しました:
s3_resource.Bucket(BUCKET).put_object(Key=new_key,
Body=edited_image_obj,
CacheControl='max-age=12312312',
ContentType=content_type)
すべてが機能することを検証するために、新しい画像ディメンションがCloudFrontのキャッシュヘッダーと共に提供されることがわかりました。
あなたは正しい軌道に乗っています...多分...しかし、少なくとも2つの問題があります。
ここで設定している「Lambda Function Association」はLambda @ Edgeと呼ばれ、まだ使用できません。アクセスできるユーザーは、限定プレビューへの参加を申し込んだユーザーのみです。 "maximum allowed is 0"
エラーは、あなたがプレビュー参加者ではないことを意味します。これがすべてのアカウントで公開される時期に関連するアナウンスを見たことがありません。
しかし、それが利用可能になったとしても、Origin Responseトリガーを使用してCloudFrontをトリガーして別の宛先を試行し、リダイレクト。この主張に反するドキュメントを見つけた場合は、私にお知らせください。
ただし... Lambda @ Edgeは307にCache-Control: no-cache
を設定するのに役立つため、CloudFrontはそれをキャッシュしませんが、リダイレクト自体は引き続きブラウザーに戻る必要があります。
また、Lambda @ EdgeはPythonではなくNodeのみをサポートしているので、これはまだ計画の一部ではないかもしれません。質問からは、私には本当にわかりません。
Lambda @ Edge限定プレビューについてお読みください 。
2番目の問題:
パスパターン
-\d+x\d+\..+$
を設定しようとしています
それはできません。パスパターンは、*
ワイルドカードをサポートする文字列の一致です。正規表現ではありません。 複数のワイルドカードがサポートされているように見える であるため、/*-*x*.jpg
でうまくいくかもしれません。