Vue.js で作ったウェブアプリは、静的サイトとして AWS S3 + CloudFront からホスティングできます。
非常にコスパのいいオススメの設計なのですが、S3 内の本番ファイルを更新した場合、CloudFront のエッジサーバ上に残っているキャッシュのせいで、その更新は即座に反映されません。
CloudFront のコンソールから「Invalidation」を手動で実行すればそのキャッシュを削除できます。
今回は、その Invalidation 手動実行の部分を AWS Lambda を使って自動化するやり方を整理します。
前提
静的サイト(特に Vue.js)を S3 + CloudFront でホストしているケースを前提としています。
Lambda を使った Invalidation の自動化手順
IAM ロールの作成
まず Lambda 関数に適用する IAM ロールの準備です。
IAM コンソールから新しいロールを作成します。ロールを使用する権限は「Lambda」、権限内容は以下の JSON で指定します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"cloudfront:CreateInvalidation"
],
"Resource": [
"*"
]
}
]
}
「Automatic Cloudfront invalidation with Amazon Lambda」より引用
ロール名は「lambda_cloud_front_invalidation」など分かりやすい適当な名前にしましょう。
Lambda 関数の作成
続いて Lambda 関数の作成です。
関数の作成
Lambda コンソールから新しい関数を作成します。今回、ランタイムで使用する言語は「Python 2.7」、実行ロールは既存のロールから「先ほど作成した IAM ロール」を指定します。
トリガーの追加
関数のトリガーに静的サイトをホストしている S3 を追加します。イベントタイプは「すべてのオブジェクト作成イベント」を選択します。
関数コードの設定
デフォルトの設定されている関数コード lambda_function.py
を、以下の内容で更新します。
from __future__ import print_function
import boto3
import time
def lambda_handler(event, context):
path = "/dist"
for items in event["Records"]:
if path in items["s3"]["object"]["key"]:
client = boto3.client('cloudfront')
invalidation = client.create_invalidation(DistributionId='YOUR_DISTRIBUTION_ID',
InvalidationBatch={
'Paths': {
'Quantity': 1,
'Items': [path + '/*']
},
'CallerReference': str(time.time())
})
break
コード内容は、S3 の /dist
ディレクトリ内(Vue.js のビルドしたコード)の更新を検知して CloudFront の Invalidation を走らせるというものです。
YOUR_DISTRIBUTION_ID
の部分は、ご自身の の Distribution ID に置き換えてください。
稼働テスト
Lambda 関数が意図しているように動くかテストします。
S3 の対象ディレクトリ(今回は /dist
)を更新し、Lambda コンソールの「モニタリング> Error count and Success rate」で処理が成功したか確認できます。
さらに新しくブラウザを開いて、変更内容が反映されていればOKです。
請求アラーム設定もお忘れなく
意図しない高額請求が発生しないように CloudWatch のコンソール にて、請求アラームを設定しておきましょう。