5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Datastreamの宛先テーブルをTerraformで管理する

5
Last updated at Posted at 2025-12-05

はじめに

本記事では、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に組み込むと良さそうです。

  1. BigQueryに転送済みのinformation_schemaからカラム情報を取得
  2. 各カラムの型を型対応表に基づいてBigQuery型に変換
  3. datastream_metadataカラムを追加
  4. 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"]
}

参考

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?