taxin's notes

読書、勉強メモ etc.

Cloud runでSlack botを作成した時にハマったこと

はじめに

GCPのCloud runを利用してSlack botを作成した際にハマったことを備忘録として残しておきます。

Slack Bot作成時には下記のようなResourceも利用しています。

  • Cloud Scheduler: Cloud runのServiceを起動する
  • BigQuery: Cloud runからクエリを実行してTableからデータを取得する

Cloud run起動時のService Account

最小限の権限でCloud runを起動する場合には、Service Accountを新規作成して必要なRoleを紐付けます。
その状態で--service-accountのオプションで作成したService Accountを指定してCloud runを起動します。

cloud.google.com


Cloud run→BigQuery(Table)に対してクエリを投げるようなSlack bot(Cloud runのService)には、下記の権限が必要になります。
(SAに紐付けられた権限を用いて、Cloud run上のプログラムでBigQueryジョブを実行してTableを参照するため下記のようになります。)

  • bigquery.jobs.create
  • bigquery.tables.getData
  • iam.serviceAccounts.actAs

cloud.google.com

cloud.google.com


上記の権限を利用するために、Service Accountに対して下記のRoleを紐付けます。

  • roles/bigquery.jobUser
  • roles/bigquery.dataViewer
  • roles/iam.serviceAccountUser

cloud.google.com


(+α)別ProjectのBigQuery(Table)にクエリを投げる

Cloud runが起動しているProject(A)から別Project(B)のBigQuery(Table)にクエリを投げるケースがあります。
先述のBigQuery関連のRoleは、下記のGCP ProjectのIAM RoleをService Accountに紐づけます。

  • roles/bigquery.jobUser → Project(A)
  • roles/bigquery.dataViewer → Project(B)

これは、BigQueryのジョブをCloud run上から実行することから、roles/bigquery.jobUserの権限はCloud runが属しているProject(A)側にアタッチする必要があるためです。

REST API ライブラリまたはクライアント ライブラリを使用して
プログラムで BigQuery ジョブを実行するには、次のようにします。

  1. クライアント コードによって生成された一意のジョブ ID を使用して、jobs.insert メソッドを呼び出す
  2. 定期的にジョブリソースをリクエストし、ステータス プロパティを調べて、ジョブの完了を確認する
  3. ジョブが正常に終了したかどうかを確認します

cloud.google.com


Cloud Scheduler用のService Account

Cloud Scheduler→Cloud runでServiceを起動する際には、Cloud Scheduler用のService AccountにCloud Run Invokerを付与する必要があります。
(手順的には下記のドキュメントが参考になります。)

cloud.google.com

また、注意点として先述のService Accountとは別にCloud Scheduler Service AgentのRoleが付与されたService Account (service-[project-number]@gcp-sa-cloudscheduler.iam.gserviceaccount.com) が必要になります。

本来は、Cloud Scheduler API を有効にする際に自動的にService Accountが作成されます。
ただし、2019年3月19日より前にこの API を有効にしていた場合は、この役割を手動で追加する必要があります。

cloud.google.com


リージョンを跨ぐ状態でのCloud Scheduler → Cloud runの起動

通常の状態では、(同一のGCP Projectであっても) リージョンを跨ぐ状態でのCloud Scheduler → Cloud runを起動することはできません。

これは、Cloud Scheduler, Cloud runが両方ともRegionに紐づくリソースで、Cloud SchedulerからのRequestはGCPのNetwork(VPC?)を利用するため、VPC周りの設定次第では到達しないためと考えられます。 (明示的に公式ドキュメントに記載してある部分は見つけることができませんでしたが、ahmetb/cloud-run-faqに記載がありました。)

If any other private service (e.g. GCE VMs, GKE) needs to call 
your Cloud Run application, they need to use this public hostname.

However, despite you’re making requests to public IP from a GCE VM 
in the same region (or possibly on cross-region if you're on GCP Premium network tier), 
the traffic won’t leave Google’s own network.

github.com

未検証ではありますが、Serverless VPC Access Connectorを利用することでこの部分は解決できるかもしれません。 cloud.google.com

終わりに

Cloud run自体は簡単に利用できますが、他サービスとの連携面などで注意する点があります。
このBlog記事がCloud runを利用する方の助けになれば幸いです。