GCPのCloud Pub/SubではpushサブスクリプションでCloud Runなどのサーバレスリソースを呼び出す際に組み込みのトークン認証機能を使用でき簡単に安全な通信を実現することができます。
Cloud Pub/SubからCloud Runを認証付きで呼び出す方法は公式ドキュメントがわかりやすいです。
しかし、ドキュメント記載の方法はCloud Pub/SubとCloud Runが同一GCPプロジェクト内にあることを前提としているため、本記事ではCloud Pub/Sunから別のGCPプロジェクトにあるCloud Runを呼び出す場合の設定方法を説明したいと思います。
手順
Cloud Pub/SubがあるGCPプロジェクトとCloud RunのサービスがあるGCPプロジェクトの名前はそれぞれ以下の名前であると仮定して説明します。
- project-pubsub: Cloud Pub/SubがあるGCPプロジェクト名
- project-run: Cloud Pub/SubがあるGCPプロジェクト名
まず、project-pubsubのCloud Pub/Subでproject-run側のリソースへアクセスする際の認証トークンを発行できるようにするために、project-run側で以下のIAMロールを付与します。
gcloud projects add-iam-policy-binding project-run \
--member=serviceAccount:service-[project-pubsubのproject number]@gcp-sa-pubsub.iam.gserviceaccount.com \
--role=roles/iam.serviceAccountTokenCreator
次に、Cloud Runサービスのエンドポイントへのアクセス権限を持つサービスアカウントをproject-pubsubで作成します。
gcloud iam service-accounts create [サービスアカウント名] --project project-pubsub
gcloud run services add-iam-policy-binding [Cloud Runのサービス名] \
--member=serviceAccount:[サービスアカウント名]@project-pubsub.iam.gserviceaccount.com \
--role=roles/run.invoker \
--project project-run
最後に、pushの宛先となるCloud Runのサービスのエンドポイントと作成したサービスアカウントを認証で使用するサービスアカウントを指定してCloud Pub/Subのサブスクリプションを作成します。
gcloud pubsub subscriptions create [サブスクリプション名] --topic [トピック名] \
--push-endpoint=[cloud runのエンドポイント] \
--push-auth-service-account=[サービスアカウント名]@project-pubsub.iam.gserviceaccount.com \
--project project-run
以上の設定でCloud Pub/Subから別のGCPプロジェクトにあるCloud Runを認証付きで呼び出すことができるようになります。
Cloud Pub/SubからCloud Runを呼ぶ時に気を付けること
Cloud Pub/Subではpushサブスクリプションを作成すると、デフォルトでは通知したメッセージに対してpush先からNACKが返ってきたら瞬時に再送処理を行います。
例えば、push先のCloud Runに問題がありpush先として指定したCloud Runのエンドポイントを叩いても5xx系エラーが返ってしまう状態になっていた場合、Cloud Pub/Subは何度もそのエンドポイントを叩き続けます。
その結果、Cloud Run側で大量のエラーログをデフォルトのログ出力先であるCloud Loggingに吐き続け、意図せぬコスト増に繋がる可能性があるので注意が必要です。
この問題を回避するためにpushサブスクリプション側では以下の設定を行っておくとよいでしょう。
- pushサブスクリプションの
Retry policy
の設定において、デフォルトのRetry immediately
ではなくRetry after exponential backoff delay
を指定し、再送処理の間隔を適切に空ける数値設定を行う。 - pushサブスクリプションの
Message retention duration
を短く設定し、長時間メッセージを保持しないようにする。