はじめに
S3+CloudFrontでホスティングされているプロジェクトでCodePipelineでS3へのデプロイ後にCloudFrontのキャッシュを自動で削除するLambda関数を作成しました。
備忘録として残します。あくまでも簡易的な実装例の1つとして参照してください。
概要
HTML/CSS/JavaScriptで構成されている静的サイト。
S3でホスティングしCloudFrontから配信している。
CI/CDがCodePipelineで自動化されている。
CloudFrontのキャッシュの削除を手動でマネジメントコンソールから行っていた。
実装
1. キャッシュ削除を行うLambda関数を実装
今回、Lambda関数はPythonで実装する。
import boto3
import time
import os
# Lambdaのエントリーポイント
# HP本番環境のCloudFrontディストリビューションに対してキャッシュ削除を行う
def lambda_handler(event, context):
    client = boto3.client('cloudfront')
    pipeline = boto3.client('codepipeline')
    try:
        # HP本番環境のディストリビューションIDを指定してキャッシュ削除を実行
        invalidation = client.create_invalidation(DistributionId='【ここにCloudFrontのディストリビューションIDを記載】',
            InvalidationBatch={
                'Paths': {
                    'Quantity': 1,
                    'Items': ['/*']
            },
            # CallerReferenceは一意になるように設定する必要があるため、現在時刻を設定
            'CallerReference': str(time.time())
        })
         # CodePipeline ジョブIDを取得
        job_id = event['CodePipeline.job']['id']
        # CodePipeline に成功レスポンスを送信
        pipeline.put_job_success_result(jobId=job_id)
    except Exception as e:
        # CodePipelineのジョブIDを指定して失敗を通知
        pipeline.put_job_failure_result(
            jobId=job_id,
            failureDetails={
                "type": "JobFailed",
                "message": str(e),
            },
        )
要点を説明すると、
- CodePipelineから呼び出されることを前提にキャッシュを全削除する。
 - キャッシュ削除をする際にCallerReferenceが一意である必要があるので現在時刻を設定
 - CodePipelineのジョブIDを取得してキャッシュ削除が完了したことをCodePipelineへ通知する
 
2. Lambda関数用のIAMポリシーを編集
Lambda関数に関連付けしているIAMロールにアタッチされているIAMポリシーに必要な権限を追加する。
CodePipelineへ実行結果を通知するために
- “codepipeline:PutJobFailureResult"
 - "codepipeline:PutJobSuccessResult"
 
Lambda関数がCloudFrontのキャッシュを削除するために
- "cloudfront:CreateInvalidation”
の権限を許可する。 
3. CodePipelineを編集
S3へのデプロイが完了した後に新しくステージを追加し、アクションプロバイダーをAWS Lambdaに設定する。
2.で実装したLambda関数を呼び出す。
4. 動作確認
デプロイを実行し、CloudFrontの対象のディストリビューションのキャッシュ削除の履歴を確認し、実行されていることを確認する。