LoginSignup
0
0

GitHub Actions + SQS + Lambda で main ブランチへ merge してから15分後に cloudfront キャッシュを削除する

Posted at

処理の概要

  1. GiHub Actions から、AWS SQS にメッセージを送信
  2. SQS がメッセージ受け取ったら、15分後に Lambda を呼び出す
  3. Lambda が aws create-invalidation コマンドを利用し、CloudFront キャッシュ削除を行う

何故そんな回りくどい事をするのか?

普通に GitHub Actions から create-invalidation を利用していましたが、AWS ECS を利用しているため古いタスクが終了し新しいタスクに切り替わる前に再度ユーザーがアクセスし、古いタスクのキャッシュが生成されるという状態になっていました

main ブランチへの merge から10分程度で ECS のタスクが切り替わっているので、余裕を持って15分後くらいにはキャッシュを削除させたかった

全体図

AWS.drawio.png

手順

Lambda の作成

2個所のみ設定で問題ありません。詳細設定などは必要があれば設定してください。

関数名 : (※任意。create-invalidation とかでもOK)
ランタイム : Node.js 20.x

CreateLambda.png

※雀の涙かもしれないですが、コストを少しでも減らしたいのでしたらアーキテクチャに「arm64」を選択

作成した Lambda 関数に権限を追加する

作成した関数に移動し、「設定 → アクセス権限 → ロール名」を順にクリック

スクリーンショット 2024-04-10 125218.png

「権限の追加」を選択

スクリーンショット 2024-04-10 125508.png

Cloud Front のキャッシュを削除するための権限

「CloudFrontFullAccess」を付与

※必要なのは「cloudfront:CreateInvalidation」だけなので、カスタム権限を作成してもいいです

SQS と連携するための権限

「AWSLambdaSQSQueueExecutionRole」を付与

Lambda コード

Lambda 関数に戻り、「コード」を選択

スクリーンショット 2024-04-10 130024.png

大きな赤枠に下記のコードをペーストしてください

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 画面のこちら

スクリーンショット 2024-04-10 130336.png

メッセージを受信するSQSを作成

SQS → キューを作成 をクリック

名前:(※任意)
受信遅延:15分に設定

それ以外の設定はお好み。

スクリーンショット 2024-04-10 130636.png

Lambda 関数に SQS をトリガーとして登録

「トリガーを追加」を選択

スクリーンショット 2024-04-10 131038.png

SQSを選択
SQS queue : 先程作成した SQS を選択
Activate trigger にチェック

スクリーンショット 2024-04-10 131223.png

で準備完了

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 なりして動作確認

お疲れ様でした

まとめ

インフラの理解がイマイチなのでこの方法になりましたが、もっといい方法あるかも。いやきっとある。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0