処理の概要
- GiHub Actions から、AWS SQS にメッセージを送信
- SQS がメッセージ受け取ったら、15分後に Lambda を呼び出す
- Lambda が aws create-invalidation コマンドを利用し、CloudFront キャッシュ削除を行う
何故そんな回りくどい事をするのか?
普通に GitHub Actions から create-invalidation を利用していましたが、AWS ECS を利用しているため古いタスクが終了し新しいタスクに切り替わる前に再度ユーザーがアクセスし、古いタスクのキャッシュが生成されるという状態になっていました
main ブランチへの merge から10分程度で ECS のタスクが切り替わっているので、余裕を持って15分後くらいにはキャッシュを削除させたかった
全体図
手順
Lambda の作成
2個所のみ設定で問題ありません。詳細設定などは必要があれば設定してください。
関数名 : (※任意。create-invalidation とかでもOK)
ランタイム : Node.js 20.x
※雀の涙かもしれないですが、コストを少しでも減らしたいのでしたらアーキテクチャに「arm64」を選択
作成した Lambda 関数に権限を追加する
作成した関数に移動し、「設定 → アクセス権限 → ロール名」を順にクリック
「権限の追加」を選択
Cloud Front のキャッシュを削除するための権限
「CloudFrontFullAccess」を付与
※必要なのは「cloudfront:CreateInvalidation」だけなので、カスタム権限を作成してもいいです
SQS と連携するための権限
「AWSLambdaSQSQueueExecutionRole」を付与
Lambda コード
Lambda 関数に戻り、「コード」を選択
大きな赤枠に下記のコードをペーストしてください
import { CloudFrontClient, CreateInvalidationCommand } from "@aws-sdk/client-cloudfront";
const cloudfront = new CloudFrontClient({ region: "us-east-1" });
export async function handler(event) {
// xxxxxxxxxxxxxx にはキャッシュを削除したい cloudfront のディストリビューションidを入力
const distributionIds = [
'xxxxxxxxxxxxxx',
];
for (const distributionId of distributionIds) {
const command = new CreateInvalidationCommand({
DistributionId: distributionId,
InvalidationBatch: {
CallerReference: `jcation-invalidation-${Date.now()}`,
Paths: {
Quantity: 1,
Items: [
"/rentacar/*"
],
},
},
});
try {
const response = await cloudfront.send(command);
console.log(response);
} catch (error) {
throw new Error(error);
}
}
}
CloudFront のディストリビューションid とは
CloudFront 画面のこちら
メッセージを受信するSQSを作成
SQS → キューを作成 をクリック
名前:(※任意)
受信遅延:15分に設定
それ以外の設定はお好み。
Lambda 関数に SQS をトリガーとして登録
「トリガーを追加」を選択
SQSを選択
SQS queue : 先程作成した SQS を選択
Activate trigger にチェック
で準備完了
GitHub Actions
下記の yml を workflows に追加
※ --message-body に "trigger" としていますが、何でもOK。好きな言葉を入れてください
name: CloudFront Clear Cache
on:
workflow_dispatch:
push:
branches:
- main
jobs:
cloudront-clear-cache:
runs-on: ubuntu-latest
steps:
- name: Send message to SQS queue
run: |
aws sqs send-message --queue-url https://sqs.ap-northeast-1.amazonaws.com/{AWS Account ID}/{SQSキューの名前} --message-body "trigger"
main に push なり merge なりして動作確認
お疲れ様でした
まとめ
インフラの理解がイマイチなのでこの方法になりましたが、もっといい方法あるかも。いやきっとある。