S3+CloudFrontにてファイル更新の際にInvalidationを行うLambda関数の作成

S3のファイルが更新されたらCloudFrontのキャッシュをクリアしたいので、S3の更新をトリガーとしたLambda関数を作ってInvalidationを発行する。

以下手順書的な。

関数の作成

  • 分かりやすい関数名を入力
  • ランタイム Python3.7を選択
  • 実行ロールはデフォルトのまま(基本的なLambdaアクセス権限で新しいロールを作成)

トリガーを追加

  • トリガーを選択 -> S3
  • バケットを選択
  • 他はデフォルトのまま(必要があれば編集)
  • 追加をクリック

コードの編集

CloudFrontのDistributionIdを以下のコードのxxxxxxxxxxに埋め込む。

lambda_function.py

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='xxxxxxxxxx',
        InvalidationBatch={
            'Paths': {
                'Quantity': 1,
                'Items': [path]
        },
        'CallerReference': str(time.time())
    })

備考

更新されたファイルごとにInvalidationが発行されるため、S3のファイルの更新頻度が高い場合はInvalidationの料金がかさむ(月1000件までは無料。それ以上は1件ごとに$0.005)点に注意。

問題になりそうなときはトリガーのプレフィックスとサフィックスを調整して、フラグとなるファイルが更新された場合のみItemsに「/*」(すべてのファイル)を指定して全クリアするのがいいだろう。例えば「trigger.invalidation」というファイルが更新された場合のみキャッシュクリアするなど。少し運用でカバー的な話になるが。

アクセス権限

  • アクセス権限のタブを開く
  • 実行ロール 編集をクリック
  • IAMコンソールで表示をクリック
  • アクセス権限 ポリシーをクリック
  • ポリシーの編集をクリック
  • ビジュアルエディタ さらにアクセス許可を追加する
  • サービス名 CloudFront
  • アクション CreateInvalidation
  • ポリシーの確認
  • 変更の保存

参考