はじめに
本記事では、Datastreamの宛先テーブルをTerraformで管理する方法について紹介します。
Datastreamのデフォルト動作とTerraform管理
Datastreamは宛先テーブルを自動作成し、スキーマ変更にも自動で追従してくれます。多くの場合はこれで十分かとは思います。
ただ、TerraformのようなIaCツールで事前にテーブルを作成しておくことで、主に以下のようなメリットがあります。
- スキーマ変更をPRベースで管理できる
- カラムレベルアクセスコントロールを導入している場合、テーブル作成時からポリシータグを付与できる
本記事ではこの方法の一例を紹介します。
Terraform管理する場合のポイント
Terraformで宛先テーブルを管理する場合、いくつか押さえておくポイントがあります。
ソースDBとBigQueryでは型が異なる
ソースDBとBigQueryでは型が異なるため、変換が必要です。本記事ではMySQLを例に説明しますが、対応表を変更すればOracle、PostgreSQL、SQL Serverなど他のソースにも適用できます。
Data type mappings in BigQuery より主要な型対応表:
| MySQL | BigQuery |
|---|---|
| VARCHAR, CHAR, TEXT | STRING |
| BIGINT, INT, TINYINT など | INT64 |
| DECIMAL (precision≤38, scale≤9) | NUMERIC |
| FLOAT, DOUBLE | FLOAT64 |
| DATE | DATE |
| DATETIME | DATETIME |
| TIMESTAMP | TIMESTAMP |
| BOOL | INT64 |
MySQLのBOOLはBigQueryではINT64になる点は注意が必要です。
datastream_metadataカラム
Datastreamは各テーブルにdatastream_metadataというSTRUCT型のカラムを追加します。事前にテーブルを作成する場合、このカラムを含めておく必要があります。
なお、このカラムの構造はWrite Modeによって異なります。以下はMergeモードの場合です(Append-onlyモードでは追加のフィールドが含まれます)。
- name: datastream_metadata
type: RECORD
fields:
- name: uuid
type: STRING
- name: source_timestamp
type: INT64
スキーマ定義の自動生成
テーブル数が多い場合、スキーマ定義を手書きするのは大変です。MySQLのinformation_schemaからスキーマ情報を取得し、型対応表を適用して自動生成する仕組みがあると便利です。あくまで以下は一例です。
全体の流れ
MySQL information_schema
│
│ バッチで転送
▼
BigQuery(スキーマ情報)
│
│ スキーマ生成スクリプト + 型対応表
▼
スキーマ定義ファイル
│
│ Terraform apply
▼
BigQuery テーブル
なお、Datastreamはbinlogベースでの連携のためinformation_schema連携はサポートしておらず、現時点(2025年12月)では別経路で転送する必要があります。
生成されるスキーマ定義の例
最終的にこのようなスキーマファイルが出力されることを目標にします。
この際、もしあればポリシータグもスキーマファイルに出力してあげると便利です。
primary_key:
- id
cluster_column:
- id
schema:
- name: id
type: INT64
mode: NULLABLE
- name: email
type: STRING
mode: NULLABLE
policyTags:
names:
- projects/xxx/locations/us/taxonomies/123/policyTags/456
- name: created_at
type: DATETIME
mode: NULLABLE
- name: datastream_metadata
type: RECORD
fields:
- name: uuid
type: STRING
- name: source_timestamp
type: INT64
型対応表
型対応表もYAMLなどで用意すれば良さそうです。
mysql:
bigint: INT64
int: INT64
tinyint: INT64
varchar: STRING
text: STRING
datetime: DATETIME
date: DATE
timestamp: TIMESTAMP
decimal: NUMERIC
float: FLOAT64
double: FLOAT64
スキーマ生成スクリプト
スクリプト自体はそこまで複雑ではありません。やっていることは以下の通りです。CI/CDに組み込むと良さそうです。
- BigQueryに転送済みの
information_schemaからカラム情報を取得 - 各カラムの型を型対応表に基づいてBigQuery型に変換
-
datastream_metadataカラムを追加 - YAML形式でファイルに出力
ポリシータグIDを変数にしておき、Terraform側でtemplatefileを使って変数解決するようにするとより便利かもしれません。
Terraformでの実装
生成したスキーマ定義をもとに、Terraformでテーブルを作成します。
resource "google_bigquery_table" "realtime_tables" {
for_each = fileset("${path.module}/schemas", "*.yaml")
dataset_id = google_bigquery_dataset.realtime.dataset_id
table_id = trimsuffix(basename(each.value), ".yaml")
schema = jsonencode(
yamldecode(file("${path.module}/schemas/${each.value}"))["schema"]
)
table_constraints {
primary_key {
columns = yamldecode(file("${path.module}/schemas/${each.value}"))["primary_key"]
}
}
clustering = yamldecode(file("${path.module}/schemas/${each.value}"))["cluster_column"]
}