はじめに
webアプリを作成している際、S3バケットの静的ファイルを更新したのにCloudFrontのキャッシュが残っていて、更新が反映されないという経験はありませんか?
私はこれまで更新した際に、いちいちCloudFrontのキャッシュ削除を手動で行っていました。今回はこれを自動化してみます。
構成
画像のように、S3バケットにファイルをアップロードした際に、Lambda関数をトリガーしてCloudFrontのキャッシュ削除を行います。
環境構築
自動化の前に、CloudFrontのディストリビューションを作成し、S3バケットをオリジンに設定しておきます。
既にCloudFrontでS3バケットをオリジンにしている構成がある場合は、このセクションはスキップしても構いません。
S3バケットの作成
- バケットタイプ:
汎用
- バケット名:例)
my-test-bucket-20250930
※グローバルで一意の名前にする必要があります。
他は全てデフォルトのままバケットを作成
をクリック。
S3バケットの静的ウェブサイトホスティングの有効化
S3バケット作成後、プロパティ
タブをクリックし、静的ウェブサイトホスティングセクションの編集
をクリック。
- 静的ウェブサイトホスティング:
有効にする
- インデックスドキュメント:
index.html
他は全てデフォルトのまま変更の保存
をクリック。
S3バケットにhtmlファイルをアップロード
下記のような簡単なhtmlファイルを作成し、S3バケットにアップロードします。
最終更新:
の部分は、アップロードするたびに書きかえます。
※このhtmlファイルは生成AIに作成してもらいました。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>CloudFront キャッシュ削除テスト</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 40px;
text-align: center;
}
h1 {
color: #2c3e50;
}
p {
font-size: 1.2em;
}
.timestamp {
margin-top: 20px;
font-weight: bold;
color: #e74c3c;
}
</style>
</head>
<body>
<h1>CloudFront キャッシュ削除テストページ</h1>
<p>このページを更新してS3に再アップロードしてください。</p>
<p>キャッシュ削除が自動で動作していれば、CloudFront経由でも最新内容がすぐ反映されます。</p>
<!-- デプロイごとに変更する部分 -->
<div class="timestamp">
最終更新: 2025-09-28 23:45
</div>
</body>
</html>
CloudFrontディストリビューションの作成
CloudFrontのコンソールに移動し、ディストリビューションを作成
をクリック。
ディストリビューションの作成ページが新しいUIに最近変わったみたいです。本記事では昔のUIで説明します。
昔のUIで作成する場合は、新UI上部の「Create Distribution」をクリックしてください。
- オリジンを選択:<作成したS3バケット名>.s3.ap-northeast-1.amazonaws.com
- オリジンアクセス:
Origin access control settings (recommended)
を選択し、Create new OAC
をクリック。- OACの設定は全てデフォルトのまま
Create
をクリック
- OACの設定は全てデフォルトのまま
- ウェブアプリケーションファイアウォール (WAF) :
セキュリティ保護を有効にしないでください
を選択 - 料金クラス:
北米、欧州、アジア、中東、アフリカを使用
を選択 - デフォルトルートオブジェクト:
index.html
他は全てデフォルトのままディストリビューションを作成
をクリック。
S3バケットのバケットポリシー設定
ディストリビューション作成後、Copy Policy
をクリックし、バケットポリシーをコピーします。
作成したS3バケットのアクセス許可
タブからバケットポリシーをコピペして変更の保存
をクリック。
動作確認
作成したCloudFrontディストリビューションのドメイン名(例:d123456abcdefg.cloudfront.net
)にアクセスし、S3バケットにアップロードしたhtmlファイルが表示されることを確認します。
ちなみに、CloudFrontのキャッシュが効いているか確認するために、htmlファイルの最終更新:
の部分を変更してS3バケットに再アップロードし、CloudFrontのドメイン名に再度アクセスしてみてください。
変更が反映されていなければ、キャッシュが効いていることになります。
また、画像のようにCloudFrontのキャッシュ削除を手動で行い、再度アクセスしてみてください。
最終更新:
の部分が変更されていれば、キャッシュ削除が正しく動作していることになります。
このキャッシュ削除を自動化していきます。
CloudFrontキャッシュ削除の自動化
長くなりましたが、ここからが本題です。
構成図でも示したように、S3バケットにファイルをアップロードした際に、Lambda関数をトリガーしてCloudFrontのキャッシュ削除を行います。
Lambda関数の作成
Lambdaのコンソールに移動し、関数の作成
をクリック
-
一から作成
を選択 - 関数名:例)
s3-cloudfront-invalidation
- ランタイム:
Python 3.13
- アーキテクチャ:
x86_64
他は全てデフォルトのまま関数の作成
をクリック。
Lambda関数のIAMロール設定
-
設定
タブのアクセス権限
からLambda関数の実行ロールをクリックし、IAMコンソールに移動。 -
ポリシーをアタッチ
をクリックし、CloudFrontFullAccess
を選択して許可を追加
をクリック。
Lambda関数のトリガー設定
-
設定
タブのトリガー
からトリガーを追加
をクリック - ソースを選択:
S3
- バケット:作成したS3バケット名を選択
- イベントタイプ:
すべてのオブジェクト作成イベント
を選択
他は全てデフォルトのまま追加
をクリック。
Lambda関数のコード設定
Lambda関数のコードエディタに下記コードをコピペし、デプロイ
をクリック。
import boto3
import os
from datetime import datetime
client = boto3.client("cloudfront")
DISTRIBUTION_ID = os.environ["CLOUDFRONT_DISTRIBUTION_ID"]
def lambda_handler(event, context):
client.create_invalidation(
DistributionId=DISTRIBUTION_ID,
InvalidationBatch={
"Paths": {
"Quantity": 1,
"Items": ["/index.html"]
},
"CallerReference": str(datetime.now().timestamp())
}
)
return {
"statusCode": 200,
"body": "Invalidation created"
}
Lambda関数の環境変数設定
-
設定
タブの環境変数
から編集
をクリック - 環境変数を追加:
-
CLOUDFRONT_DISTRIBUTION_ID
:作成したCloudFrontディストリビューションのIDを入力
-
動作確認
これにて設定は完了です!最後に動作確認をしてみましょう!
S3バケットにアップロードしたhtmlファイルの最終更新:
の部分を変更して再アップロードし、CloudFrontのドメイン名にアクセスしてみてください。
すぐに変更が反映されていれば、CloudFrontのキャッシュ削除が自動で動作していることになります。