🌊

Eventarcを用いてCloud Storageへのファイルアップロードイベントを検知してみた

に公開

今回はEventarcを利用して、Cloud Storageにファイルがアップロードされたことを検知してCloud Runのエンドポイントを呼び出してみました。以前Pub/Subを使ってBigQueryと連携することはしてみましたが、今回はEventarcを使ってみました。

https://zenn.dev/akasan/articles/e17a1867408c53

早速試してみる

今回は以下の公式ドキュメントを参考に進めました。

https://cloud.google.com/run/docs/tutorials/eventarc?hl=ja#before-you-begin

システム構成は以下のようになっています。

  • PCからCloud Storageにファイルをアップロードする
  • Cloud Storageに対してファイルがアップロードされたらEventarcトリガーが実行される
  • Cloud Run上のPOST /eventarcに対してリクエストが投げられる

Pythonコードの実行

以下のようなシンプルなFastAPIサーバを立てます。POST /eventarcに対してEventarcがリクエストを送信し、イベント内容をインメモリのリストに追加します。GET /itemsを呼び出すとイベント内容一覧のリストがそのまま返されます。

uv init -p 3.12
uv add fastapi uvicorn
main.py
from fastapi import FastAPI, Request


received_items = []

app = FastAPI()

@app.post("/eventarc")
async def set_item(request: Request):
    event = await request.json()
    received_items.append(event)


@app.get("/items")
def get_items():
    return received_items

こちらのコードをCloud Runにデプロイするにあたり、以下のDockerfileを利用します。

FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim

WORKDIR /app
COPY . /app

EXPOSE 8080
RUN uv sync

CMD ["uv", "run", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]

Artifact Registryのレポジトリ作成とDockerイメージのPush

先ほど作成したPythonコードをArtifact RegistryにPushするために、以下のスクリプトを実行します。

PROJECT_ID="..."
REGION="asia-northeast1"
REPOSITORY_NAME="eventarc-cloud-run-test"
IMAGE_NAME="fastapi-app"
TAG="latest"
SERVICE_NAME="fastapi-app"
PROJECT_NUMBER="..."

# Create Artifact Repository
gcloud artifacts repositories create $REPOSITORY_NAME \
	--repository-format=docker \
	--location=$REGION


# Construct the full image URL
IMAGE_URL="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/${IMAGE_NAME}:${TAG}"

echo "Building Docker image for linux/amd64 platform..."
docker build --platform linux/amd64 -t "${IMAGE_URL}" .
docker push "${IMAGE_URL}"

Cloud Storageバケットの作成

Eventarcのトリガー先となるCloud Storageバケットを作成します。

gcloud storage buckets create gs://${PROJECT_ID}-bucket/ --location=${REGION}

Cloud Runのデプロイ

先ほど作成したArtifact Registryのレポジトリからイメージを取得して、Cloud Run上にFastAPIサーバを立てます。

gcloud run deploy ${SERVICE_NAME} --image ${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/${SERVICE_NAME}:${TAG}

今回は公開エンドポイントとしてデプロイしました。サービスが作成された後に/docsにアクセスするとSwagger UIが確認できます。

Eventarcトリガーの作成

それでは本題のトリガーを作成してみましょう。今まで作成したCloud RunとCloud Storageを対象にして、以下のようにしてトリガーを作成します。イベント送信先のCloud Runサービスは--destination-run-serviceで指定し、イベント送信用のエンドポイントとして--destination-run-path=/eventrcを指定しています。また、ファイルのアップロードを検知する対象のストレージは--event-filters=bucket=${PROJECT_ID}-bucketのようにして指定しています。

gcloud eventarc triggers create ${SERVICE_NAME} \
	--destination-run-service=${SERVICE_NAME} \
	--destination-run-region=${REGION} \
	--location=${REGION} \
	--event-filters="type=google.cloud.storage.object.v1.finalized" \
	--event-filters="bucket=${PROJECT_ID}-bucket" \
	--service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com \
	--destination-run-path=/eventarc

動作チェックしてみる

それではまずはファイルアップロード前のアイテム一覧を取得してみます。Swagger UIから実行した結果、以下のようにまだ何もリストには登録されていないことがわかります。

次にバケットにファイルをアップロードしてみましょう。試しに一番最初に貼り付けたアーキテクチャ図(arch.png)をアップロードしてみます。

その後に再度Swagger UIでGET /itemsを実行すると、以下のようにイベント情報が記録されていることが確認できました。内容を見ると、mediaLink/selfLinkに登録したファイル名が記録されていたり、ストレージクラスや登録日時が記録されていることがわかりました。この構成を利用することで、アップロードされたファイルに対してのみ処理を実行するといった利用方法があるかと思います。

まとめ

今回はEventarcを用いてイベントをトリガーし、Cloud Storageへのファイルアップロード情報をCloud Runに伝えてみました。MLの分野で言うとファイルの前処理などのトリガーとして使う機会があると思うので、今後もっと色々なパイプラインをEventarcで組んでみようと思います。

Discussion