AWS Lambdaを使用し、CloudfrontのInvalidationを走らせる
こんにちは。エンジニアの志村です。
先日assets on S3についての実装を行いました。
その際の記事は下記になります。
今回はasset_syncにより、S3にassetファイルがアップロードされた段階でCloudfrontのInvalidationをLambdaを使用して走らせるという処理を実装したいと思います!
Invalidationとは
Cloudfrontのキャッシュを明示的に消す機能です。
クラスメソッドさんの上記の記事が非常に分かりやすいかと思います。
キャッシュを使用するのに重要なポイントは適切なキャッシュ期間を設けることです。それを行わないと古いファイルがいつまで経っても配信され続けてしまいます。
特にassets on S3を使用する場合には、明示的にファイルをInvalidationしないといつまで経っても最新のassetsファイルがユーザーに配信されなくなります。
このような状況を防ぐために、S3にファイルが転送された段階で、assetsのキャッシュを消去する必要があります。
Lambdaの実装
ではLambdaの実装を始めていきます。
AWSコンソールからLambdaを選択します
「Create Lambda Function」を選択します
今回はBlueprintは使用しないので「Skip」を選択します
S3を選択します。
項目 | 説明 |
---|---|
Bucket | assets用のBucketを選択 |
Event Type | S3にassetsファイルがCreateされた段階でInvalidationを走らせたいので「Object Created(All)」を選択 |
Enable Trigger | チェックを入れると、設定したイベントが走るようになります(production等で設定する場合は注意!) |
※Prefix, Suffixは必要であれば入力して下さい。
LambdaFunctionを作成します
項目 | 説明 |
---|---|
Name | 適当な名前を入力 |
Description | 分かりやすい説明を入力 |
Runtime | 今回はPythonにします |
コードは下記のコードが非常に分かりやすかったのでそれを使用します。
※DistributionIDは自身のCloudfrontディストリビューションのIDを入力して下さい
from __future__ import print_function import boto3 import time def lambda_handler(event, context): for items in event["Records"]: path = "/" + items["s3"]["object"]["key"] print(path) client = boto3.client('cloudfront') invalidation = client.create_invalidation(DistributionId='ディストリビューションID', InvalidationBatch={ 'Paths': { 'Quantity': 1, 'Items': [path] }, 'CallerReference': str(time.time()) })
因みにですが、boto3はPython用のAWS SDKです。 Lambda FunctionをPythonで書く際には必ずと言って良いほど良く使用します。 ドキュメントも充実しているので非常に使い勝手が良いと思います。
Boto 3 Documentation — Boto 3 Docs 1.4.0 documentation
ロールやその他の設定をします
「Lambda function handler and role」のRole→「Create a custom role」を選択します。
そうすると下記のような画面が現れるので、下記のCloudfrontのInvalidationを許可するロールを作成します。
下記のようなポリシードキュメントになります。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:*" }, { "Effect": "Allow", "Action": [ "cloudfront:CreateInvalidation" ], "Resource": [ "*" ] } ] }
最後に「Create function」を押下すれば完成です!
使い方
asset_syncでデプロイすると勝手にInvalidationが走ってくれます。 下記の画面で確認が出来ます。
AWSコンソールからCloudfrontを選択します
該当するディストリビューションのIDを選択します
「Invalidations」タブを選択すると、Invalidationsの状態が閲覧出来ます。ここでデプロイ直後にStatusがProgressとなっていればトリガーがきちんと走っています。
以上になります。 キャッシュの扱いって本当難しいなーと感じますが、この様に自動化してしまえば特に意識することも少なくなって、よりCloudfrontが使いやすくなりますね。