🦧

Cloud Function Gen2 スケジュール実行

2023/01/05に公開

Cloud Function Gen2 スケジュール実行

cloud functionsの第二世代が登場したので、スケジューラーから実行をしてみる。

概要

簡単なバッチ処理をエンタープライズ環境で実施することを想定する。
そのため、許可された対象からのみ実行できるように作成する。

Cloud functions Gen2(第二世代)

第二世代になってなにが変わったかについて軽く説明。
下記をおぼえておけばとりあえずはOK

  • Eventarc を使用した 125 を超える Google やサードパーティによる SaaS イベントからの新しいトリガーに対応
  • Cloud Runベースで実行されるため、HTTP関数として作成した場合はタイムアウトが60分に
    • GCSトリガーなどの場合は今まで通り9分制限という点に注意
  • 多様なデプロイ、ロールバック手段に対応
    • カナリアとか
  • 最大16GBのRAM と4つのvCPU

詳細は公式のブログを参照
https://cloud.google.com/blog/ja/products/serverless/cloud-functions-2nd-generation-now-generally-available

事前準備

関数を作るときに必要な諸々を用意

API有効化

必要なAPIを有効化する。
コンソールから作ると足りてないAPIを有効化するように誘導される。
そのため、いきなりIaC化する前に一度コンソールから作ってみることをお勧めする。

  • gen2の場合は、Cloud RunのAPIも有効化が必要
  • Eventarcトリガーを使用する場合は、Eventarc APIの有効化が必要

サービスアカウント

cloud functionsとpubsubで使う用のSAを用意する。

# SA作成
gcloud iam service-accounts create gen2-scheduler-test \
    --description="cloudfunctions用" \
    --display-name="gen2-scheduler-test"
# 権限付与
gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="serviceAccount:SA_NAME@PROJECT_ID.iam.gserviceaccount.com" \
    --role="roles/iam.serviceAccountTokenCreator"

Function作成

コンソールからポチポチつくる。
コードはサンプルをそのまま利用する。

CUIで作るときはこんな感じ

gcloud functions deploy YOUR_FUNCTION_NAME \
	[--gen2] \
	--region=asia-northeast1 \
	--runtime=YOUR_RUNTIME \
	--source=YOUR_SOURCE_LOCATION \
	--entry-point=helloHttp \
	--trigger-http 

こんな感じでCloud Runの魔法が漏れ出している。

Schedulerから起動

いよいよ本題

Cloud pubsub

# topic
gcloud pubsub topics create scheduler-test-topic

# subscription
gcloud pubsub subscriptions create scheduler-test-subscription \
	--topic=scheduler-test-topic \
	--push-auth-service-account=${SERVICE_ACCOUNT_EMAIL} \
	--push-endpoint=${PUSH_ENDPOINT_URI}

Cloud Scheduler

gcloud scheduler jobs create pubsub scheduler-test-job \
    --location=asia-northeast1 \
    --schedule="*/10 * * * *" \
    --topic=scheduler-test-topic \
    --message-body "Hello"

実行結果

まずは普通にURIを叩いて、実行されないことを確認

次はSchedulerから実行されることを確認

認証エラー…

The request was not authenticated. Either allow unauthenticated invocations or set the proper Authorization header. Read more at https://cloud.google.com/run/docs/securing/authenticating Additional troubleshooting documentation can be found at: https://cloud.google.com/run/docs/troubleshooting#unauthorized-client"

push-auth-token-audienceに"Authorization: bearer $(gcloud auth print-identity-token)"を追加して再チャレンジ

次はこのエラー

"The request was not authorized to invoke this service. Read more at https://cloud.google.com/run/docs/securing/authenticating Additional troubleshooting documentation can be found at: https://cloud.google.com/run/docs/troubleshooting#401"

roles/cloudfunctions.invokerの権限を追加して再チャレンジ
公式ページに記載ありました。

HTTP トリガー: 関数への HTTP トリガーとして Pub/Sub push リクエストを使用する場合、関数を呼び出すには、push 認証サービス アカウントに roles/cloudfunctions.invoker のロールが必要です。

指示されたページを見ると次のようにあったので、push-auth-token-audienceに"Authorization: bearer $(gcloud auth print-identity-token)"を削除

認証トークンの形式が無効な場合は、401 エラーがスローされます。トークンが有効な形式で、トークンの生成に使用された IAM メンバーに run.routes.invoke 権限がない場合、この 403 エラーが発生します。

成功!cloud functionの権限がたりないだけでした。

Discussion