TerraformでBigQueryをIaC化してみた

こんにちは、SCSKの齋藤です。

本記事では、Terraformを使ってBigQueryのリソース(データセット・テーブル・スキーマ)をInfrastructure as Code(IaC)として管理する方法を解説します。

 

そもそもBigQueryとは?

BigQueryは、Google Cloudが提供するサーバーレスなデータウェアハウスです。
特徴は以下の通りです。

  • SQLで大規模データを高速分析
    標準SQLでペタバイト級のデータを数秒〜数分で集計・分析。
  • サーバーレス
    インフラ管理不要。ストレージやクエリのリソースは自動でスケール。
  • コスト効率
    ストレージとクエリ課金が分離されており、使った分だけ支払う従量課金。
  • GCPサービスとの連携
    Cloud Storage、Dataflow、Looker Studio など、他の GCP サービスとシームレスに連携。 これにより、データの収集、処理、可視化を統合的に行うことが可能。

なぜTerraformでBigQueryを管理するのか?

BigQueryはGCPコンソールやbqコマンドで手軽にテーブル作成できますが、TerraformでIaC化することで以下のメリットがあります。

  • 環境ごとの再現性
    開発 (dev)、ステージング (stg)、本番 (prd) など、異なる環境で同じ構成をコードで再現できます。環境の違いによる「あれ?動かない…」を撲滅!
  • スキーマや設定のバージョン管理
    テーブル定義、パーティション設定、クラスタリング設定などの変更履歴を Git で管理できます。 これにより、変更の追跡、ロールバック、監査が容易!
  • 自動化・レビュー
    Pull Request (PR) ベースでレビューを行い、CI/CD (Continuous Integration/Continuous Delivery) パイプラインによる自動反映が可能です。 これにより、変更の品質を向上させ、デプロイメントの効率アップ!
  • ヒューマンエラー防止
    手作業による設定ミスや漏れを防ぐことができます。 コードによる定義は、人為的な誤りを減らし、一貫性を保証!

ディレクトリ構造例

本記事で紹介する構成は、プロジェクトごと・データセットごとにモジュールを分割し、環境(dev/stg/prd)ごとにパラメータを切り替えられるようにしています。

terraform-bigquery/
└── プロジェクト名/
    ├── envs/
    │   │── dev/
    │   │   ├── main.tf
    │   │   ├── backend.tf
    │   │   ├── provider.tf
    │   │   ├── terraform.tfvars
    │   │   └── variables.tf
    │   └── stg/
    │   └── prd/
    └── module/
        └── dataset1/
            ├── table1.yaml      # テーブルスキーマ(YAML)
            ├── dataset1.tf        # データセット・テーブル定義
            └── variables.tf        # モジュール変数

各ファイルの役割:

  • envs/dev/main.tf:環境固有の設定を適用し、データセット構築に必要な各モジュールの呼び出しとその引数を定義
  • envs/dev/backend.tf:Terraform State を安全かつ共有可能な場所に保存するための設定(GCSバケットなど)
  • envs/dev/provider.tf:GCP プロバイダの認証情報、対象プロジェクト、リージョンなどを設定
  • envs/dev/terraform.tfvars:プロジェクトID、リージョン、サービスアカウントメールアドレスなど、環境によって異なる変数値の定義
  • envs/dev/variables.tf:main.tf で使用する変数の型、デフォルト値、説明などを定義し、外部からの入力インターフェースを提供
  • module/dataset1/table1.yaml:テーブルのカラム名、データ型、nullable 属性、説明などを記述した YAML 形式のスキーマ定義ファイル
  • module/dataset1/dataset1.tf:データセット自体の定義、および table1.yaml からスキーマを読み込んでテーブルを定義するTerraformリソース定義
  • module/dataset1/variables.tf:モジュール内で使用する変数(プロジェクトID、データセット名など)の型、デフォルト値、説明などを定義

実装例

envs/dev/main.tf

このファイルは、各データセットに対応するモジュールを呼び出す役割を担います。 source パラメータでモジュールの場所を指定し、project_nameregion 変数を渡します。 環境ごとに異なる terraform.tfvars ファイルを使用することで、同じコードで異なる環境をデプロイできます。

module "table1" {
  source       = "../../module/table1"
  project_name = var.project_name
  region       = var.region
}
module "table2" {
  source       = "../../module/table2"
  project_name = var.project_name
  region       = var.region
}

module/dataset1/table1.yaml

このファイルは、テーブルのスキーマを YAML 形式で定義します。 nametypemodedescription などの属性を定義することで、テーブルのカラム構造を明確に記述できます。 YAML 形式を使用することで、可読性が向上し、メンテナンスが容易になります。

- name: extraction_time
  type: DATETIME
  mode: NULLABLE
  description: "データ抽出日時"
- name: value
  type: STRING
  mode: NULLABLE
  description: "値"
# ...(以下略)

module/dataset1/dataset.tf

このファイルは、データセットとテーブルのリソースを定義します。

  • google_bigquery_dataset リソース: projectlocationdataset_id などの属性を定義して、データセットを作成します。 
  • google_bigquery_table リソース: projectdataset_idtable_iddescription などを定義して、テーブルを作成します。 。
  • schema 属性: YAML ファイルからテーブルスキーマを読み込み、yamldecode 関数で YAML 形式から Terraform で使用できる形式に変換し、さらにjsonencode関数でJSON形式にエンコードします。
  • time_partitioning ブロック: クエリのパフォーマンスを向上させるために、時間ベースのパーティショニングを設定します。 type (この例では “MONTH”) と field (パーティションキーとなるカラム名) 
  • clustering 属性: クエリのパフォーマンスを向上させるために、クラスタリングキーとなるカラム名を指定して、クラスタリングを設定します。
  • deletion_protection 属性: テーブルの削除保護を有効にします。 true に設定することで、誤ってテーブルを削除するのを防止
resource "google_bigquery_dataset" "dataset1" {
  project  = var.project_name
  location = var.region
  dataset_id = "dataset1"
}

resource "google_bigquery_table" "table1" {
  project    = google_bigquery_dataset.dataset1.project
  dataset_id = google_bigquery_dataset.dataset1.dataset_id

  table_id    = "table1"
  description = "情報を取得"
  schema      = jsonencode(yamldecode(file("${path.module}/table1.yaml")))
  time_partitioning {
    type  = "MONTH"
    field = "extraction_time"
  }
  clustering          = ["value"]
  deletion_protection = true
}

envs/dev/variables.tf

このファイルは、main.tf やモジュールで使用する変数を定義します。以下の変数は、GCP プロジェクト ID とリージョンを指定するために使用されます。

variable "project_name" {
  type = string
}
variable "region" {
  type = string
}

envs/dev/terraform.tfvars

このファイルは、環境固有の変数の値を定義します。以下の変数に、それぞれ GCP プロジェクト ID とリージョンの値を設定します。
project_name                 = "project1"
region                       = "asia-northeast1"

envs/dev/provider.tf

このファイルは、GCP プロバイダを設定します。 以下の属性に、それぞれ project_nameregion 変数を設定します。

provider "google" {
  project = var.project_name
  region  = var.region
}

  

工夫ポイント

スキーマをYAMLで管理

テーブルのカラム定義を YAML で記述し、Terraform で yamldecode → jsonencode して渡すことで、スキーマの可読性・メンテナンス性が大幅に向上します。 YAML は、構造化されたデータを記述するための人間にとって読みやすい形式であり、複雑なスキーマを管理するのに適しています。

パーティション・クラスタリングもIaCで管理

time_partitioning や clustering もコードで明示することで、クエリコスト最適化や運用ルールの徹底ができます。 
time_partitioning { type = "MONTH" field = "extraction_time" } 
clustering = ["value"] deletion_protection = true

 

部分的なplan/applyで安全に反映

以下のように、特定のデータセットやテーブルだけを対象に plan/apply できます。他のリソースに影響を与えないので安心です。

bash
terraform plan -target=module.dataset1
terraform apply -target=module.dataset1

テーブルの削除保護

deletion_protection = true を設定しておけば、間違ってテーブルを削除してしまうのを防げます。本番環境では必須の設定です。 

 

運用・変更の流れ

  • スキーマ追加・変更:
    1. 該当する YAML ファイルにカラムを追加・修正。
  • テーブル追加:
    1. module/dataset名/ に新たな YAML ファイルとリソース定義 (.tf ファイル) を追加。
  • 環境ごとに反映:
    1. dev/stg/prd の main.tf で必要なモジュールを呼び出し、terraform apply を実行。
  • バージョン管理:
    1. すべての変更を Git で管理。
    2. Pull Request ベースでレビューを行い、CI/CD パイプラインを使用して自動的にデプロイ。

まとめ

BigQueryのテーブルやスキーマ、パーティション設定をTerraformでIaC化することで、再現性・自動化・レビュー性・ヒューマンエラー防止など多くのメリットが得られます。

  • スキーマはYAMLで管理し、Terraformで読み込むと可読性・保守性が高まる
  • パーティションやクラスタリングもコードで明示し、運用ルールを徹底
  • dev/stg/prdなど複数環境も同じ構成を再現できる
  • すべてgitでバージョン管理し、Pull Requestベースで安全に運用

BigQueryの運用に課題を感じている方、これからIaCに取り組みたい方は、ぜひTerraformによるBigQuery管理を試してみてください!

 

参考リンク

著者について

SCSK株式会社
ソリューション事業グループ
基盤ソリューション事業本部

齋藤雄太をフォローする

クラウドに強いによるエンジニアブログです。

SCSKクラウドサービス(Google Cloud)は、Google Cloudの多彩なAIや各種サービスを活用したワンストップソリューションを提供します。SCSKのノウハウや体制を有効活用し、業務課題の解決に必要な全体検討と組み合わせで、最適な業務実装まで支援します。

Google Cloudクラウド
シェアする
タイトルとURLをコピーしました