CloudFront のキャッシュを Lambda から invalidation する

調べる機会があったのでメモ。

前提

Lambda 関数はこんな感じで作成。IAM ロールは別途用意。

サンプルコード

今回は、invalidation するオブジェクトパスをパラメータで指定できるようにする。パラメータ未指定の場合はデフォルトのパス (/*) で invalidation を実行する。

CallerReference は冪等性を担保する仕組みのようで呼び出しごとに一意の値を渡せばよさそう。(今回は UUID とする)

import boto3
import uuid

client = boto3.client('cloudfront')

def lambda_handler(event, context):
    distribution_id = '{distribution_id}'
    items = event['items'] if 'items' in event else ['/*']
    resp = client.create_invalidation(
        DistributionId = distribution_id,
        InvalidationBatch = {
            'Paths': {
                'Quantity': len(items),
                'Items': items
            },
            'CallerReference': str(uuid.uuid4())
        }
    )
    print('create_invalidation success:')
    print(resp)

オブジェクトパスを指定して invalidation を実行する

オブジェクトパスをパラメータに指定して Lambda を テスト実行 する。

{
    "items": [
        "/path/to/foo",
        "/path/to/bar"
    ]
}

定期的に invalidation を実行する

設定 > トリガー で EventBridge (CloudWatch Events) のトリガーを設定する。ルールタイプをスケジュール式にして rate(10 minutes) とすると10分間隔で Lambda が起動する。(cron 形式でも指定可)

(補足1)

IAM ロールにはこんな感じの IAM ポリシーをアタッチする。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudfront:CreateInvalidation"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

(補足2)

AWS CLI で CloudFront のキャッシュを invalidation する。

$ aws cloudfront create-invalidation --distribution-id {distribution_id} --paths "/path/to/foo" "/path/to/bar"

現場からは以上です。