created: 2022-09-15T07:07:39.718Z
[GCP] CloudLogging のフィルタで CloudFunction をキックする PubSub を terraform で定義する
たとえば「BigQuery でどんなクエリが発行されているかを Slack に通知したいな」という要件があった場合。
こんなログフィルタでそんなイベントを知ることができるので、このフィルタにマッチしたログが出たときに CloudFunction とかを動かせるようにする。
resource.type="bigquery_resource"
protoPayload.methodName="jobservice.jobcompleted"
実装
こんな tf ファイルの定義で CloudFunction 以外のリソースは生成できる。意外と少ない。
google_logging_project_sink
- ログを検索するクエリを管理するリソース
google_pubsub_topic
- sink に入った(検索に引っかかった)ログの情報をイベントとして処理をキックするリソース
- 具体的には CloudRun や CloudFunction の処理をキックする
resource "google_logging_project_sink" "bigquery-jobcompleted" {
destination = "pubsub.googleapis.com/projects/${var.GCP_PROJECT_ID}/topics/bigquery-jobcompleted"
name = "bigquery-jobcompleted"
filter = <<-FILTER
resource.type="bigquery_resource"
protoPayload.methodName="jobservice.jobcompleted"
FILTER
}
resource "google_pubsub_topic" "bigquery_jobcompleted" {
name = "bigquery-jobcompleted"
}
# unique_writer_identity=true で払い出される SA に pubsub を publish する権限を付与
resource "google_project_iam_member" "bigquery_jobcompleted_pubsub_writer" {
member = google_logging_project_sink.bigquery_jobcompleted.writer_identity
role = "roles/pubsub.publisher"
}
unique_writer_identity?
専用のサービスアカウントを作るかどうか。複数プロジェクトへ publish するシンクを作りたい場合は true にする必要がある。
ちなみにコンソールからポチポチ作業するとこれは true
でつくったような状態になるようだ。
(Optional) Whether or not to create a unique identity associated with this sink. If false (the default), then the writer_identity used is serviceAccount:cloud-logs@system.gserviceaccount.com. If true, then a unique service account is created and used for this sink. If you wish to publish logs across projects or utilize bigquery_options, you must set unique_writer_identity to true.
サービスアカウントへのロール付与
unique_writer_identity = true
でリソースを生成すると自動的にサービスアカウントが払い出される。このサービスアカウントは GCP のコンソールに表示されないが、これに pubsub を publish できるロールが付与されていないと権限がないということで期待通り動作しない。
確認
# sinksの情報からServiceアカウントのIDを取得
$ gcloud logging sinks describe bigquery-jobcompleted | grep serviceAccount
writerIdentity: serviceAccount:p123456@gcp-sa-logging.iam.gserviceaccount.com
$ export SERVICE_ACCOUNT="p123456@gcp-sa-logging.iam.gserviceaccount.com"
$ gcloud projects get-iam-policy \
$GCP_PROJECT_ID \
--flatten="bindings[].members" \
--format="table(bindings.role)" \
--filter="bindings.members:$SERVICE_ACCOUNT"
ROLE
roles/pubsub.publisher
terraform import
もしコンソールの検索画面から作った場合は terraform import で tfstate に取り込むことになる。
$ terraform import google_logging_project_sink.bigquery_jobcompleted projects/$GCP_PROJECT_ID/sinks/bigquery-jobcompleted
$ terraform import google_pubsub_topic.bigquery_jobcompleted bigquery-jobcompleted
参考
- google_logging_project_sink | Resources | hashicorp/google | Terraform Registry
- google_pubsub_topic | Resources | hashicorp/google | Terraform Registry
- Terraform で Logging → PubSub - pokutuna
- IAM を使用したアクセス制御 | Cloud Pub/Sub ドキュメント | Google Cloud
- Configure and manage sinks | Cloud Logging | Google Cloud