Skip to content

Commit 799dcfa

Browse files
authored
Merge pull request #1475 from future-architect/feature
NEW: Terraformでテーブル管理時のハマりどころ5選
2 parents 4b6ccfe + 176942a commit 799dcfa

7 files changed

Lines changed: 206 additions & 2 deletions

source/_posts/20250331a_Terraform連載2025を開始します.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ lede: "うららかな春の陽気と共に、2025年度がスタートしまし
5151
| 4/2(水) | 伊藤太斉 さん | Trivyを用いたTerraformでのセキュリティ戦略 |
5252
| 4/3(木) | 森友雅さん | [【Terraform】プロビジョニングとはなんぞや](/articles/20250403a/) |
5353
| 4/4(金) | 前原 応光さん | [Terraform TIPS 集](/articles/20250404a/) |
54-
| 4/7(月) | 大前七奈さん | Terraformでテーブル管理時のハマりどころ5選 |
55-
| 4/8(火) | 棚井 龍之介さん | TODO |
54+
| 4/7(月) | 大前七奈さん | [Terraformでテーブル管理時のハマりどころ5選](/articles/20250407a/) |
5655
| 4/9(水) | 伊藤太斉 さん | Terraform設計ガイドラインを公開しました(仮) |
5756

5857
チップス集やハマりどころ5選など実践的な部分から、セキュリティ戦略など理論的なところまで幅広いテーマを準備しました。
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
---
2+
title: "Terraform × BigQuery データ管理:陥りがちな落とし穴と対策5選(サンプルコード付き)"
3+
date: 2025/04/07 00:00:00
4+
postid: a
5+
tag:
6+
- Terraform
7+
- GCP
8+
- BigQuery
9+
- データマネジメント
10+
- データエンジニアリング
11+
category:
12+
- Infrastructure
13+
thumbnail: /images/20250407a/thumbnail.png
14+
author: 大前七奈
15+
lede: "Terraformは、インフラ構築をコードで管理できる強力なツールですが、BigQueryのデータ管理においては、特有の課題に直面することがあります。本記事では、TerraformでBigQueryを扱う際に陥りやすい落とし穴と、データ管理の品質を高めるための対策について、サンプルコードを交えながら解説します。"
16+
---
17+
18+
<img src="/images/20250407a/terraform_bigquery.png" alt="" width="800" height="411">
19+
20+
[Terraform 連載2025](/articles/20250331a/)の5日目です。
21+
22+
Terraformは、インフラ構築をコードで管理できる強力なツールですが、BigQueryのデータ管理においては、特有の課題に直面することがあります。本記事では、TerraformでBigQueryを扱う際に陥りやすい落とし穴と、データ管理の品質を高めるための対策について、サンプルコードを交えながら解説します。
23+
24+
ちなみに、以下の構成の前提で解説するため、事前にご了承ください。
25+
26+
<a href="https://mermaid.live/edit#pako:eNptkltvozAQhf-KNU-tRCsI4RI_VCq0kXa1uxIkTyteXDxJLIHNGrtqNsp_X5NA2m3Kky_fOXPGzAFqxREo9PjHoqzxSbCtZm0lifs6po2oRcekIeslYT1Zo9Zso_QXQFYMQCa2hUW9v77PTwZ5oywnSytrI5S8pviL-UJavktLK8l39VKN2vXy7uEhKygxUzLCuq4Z6-fT7TfZo3buzLCNaw_JzfOb0aw2t2fwlzJI1CtqMtBPDiOPnCOfyjhSvDLH5OXoXDpnF5YOiYm2n7lLH24xZhiSr4of5GatmeyHqLefRFlxPsiKu8l9ZZix_WiFV-Tg7tC8pGQppOh3_8f5oLgEem91ULmnJLVquwYNXpfJS_CgRd0ywd2QHAagArPDFiugbslxw2xjKqjk0aHMGrXayxqo0RY90Mpud0A3rOndznbu_acJmxD3g38rddkiF0bpn-ehPM2mB1s9VB8dUXLUubLSAA2Ckx7oAd6AptF9nITz2dxfLGaLJA492AOdRe44CoLF3I98P0jS-dGDv6eK_n0Up0kSxmmcplEahsnxHxOl-Us">
27+
<img src="/images/20250407a/mermaid-diagram-2025-04-07-100048.png" alt="" width="1000" height="642">
28+
</a>
29+
30+
# 1. テーブルのライフサイクル管理
31+
32+
## 課題: テーブルの意図しない変更によるデータ損失
33+
34+
Terraformは、リソースのライフサイクルをコードで管理できますが、以下のいくつのケースの際に、テーブルを再度自動作成されるため、意図しないデータ損失が発生します。
35+
- Terraform上のスキーマ変更を適用したとき
36+
- Cloud Functionなどでデータを洗い替えされ、再度`terraform apply`を実行されたとき(BigqueryAPIのJobConfigによって事前に防ぐことができます。詳しくは3.の項で)。
37+
38+
## 対策
39+
40+
`lifecycle`メタ引数を利用して、`prevent_destroy`を設定し、意図しない削除を防止します。
41+
42+
ただし、このタグの関係で、意図したスキーマ変更を実行する際に、`Instance cannot be destroyed`エラーが発生するために、プロジェクトを立ち上げる初期は、スキーマ変更が頻繁に発生する場合、おすすめしません。
43+
44+
ある程度で変更頻度が落ち着いた頃、あるいは、データの保持が必要になった頃に導入することがおすすめです。
45+
46+
```bash
47+
Terraform
48+
49+
resource "google_bigquery_table" "my_table" {
50+
dataset_id = google_bigquery_dataset.my_dataset.dataset_id
51+
table_id = "my_table"
52+
53+
lifecycle {
54+
prevent_destroy = true
55+
}
56+
#その他の設定
57+
}
58+
59+
```
60+
61+
# 2. スキーマ定義と管理
62+
63+
## 課題: スキーマ定義の不整合、変更に伴うデータ移行の複雑さ
64+
65+
Terraformで管理する場合、スキーマ定義の不整合や変更に伴うデータ移行が複雑になることがあります。体系的にスキーマを管理する必要があります。
66+
67+
## 対策
68+
69+
各スキーマをTerraform内でベタ書きでなく、Terraformの`file`関数を利用してJSONスキーマを外だしで管理すること。
70+
71+
また、`for_each`機能を利用して、各テーブルの差分(別々に管理したいプロパティ)のみをパラメータ化し、テーブルの設定に一貫性をもたせます。
72+
73+
```bash
74+
table_settings.tf
75+
76+
locals {
77+
table_setting = toset([
78+
{
79+
dataset_name = "my_dataset"
80+
table_name = "my_table"
81+
description = "テストテーブル"
82+
# 別々に管理したいテーブルのパラメータのみ
83+
},
84+
# その他のテーブル
85+
])
86+
}
87+
```
88+
89+
```bash
90+
bigquery_tables.tf
91+
92+
resource "google_bigquery_table" "my_table" {
93+
for_each = {for k, v in local.table_setting : k.table_name => v }
94+
dataset_id = each.value.dataset_name
95+
table_id = each.value.table_name
96+
schema = <<EOF
97+
${file("${path.root}/schemas/${each.value.dataset_name}/${each.value.table_name}.json")}
98+
EOF
99+
# その他固定化する項目
100+
}
101+
```
102+
103+
# 3. スキーマの変更管理(望ましくない変更がないように)
104+
105+
## 課題: データの不整合、品質劣化
106+
107+
BigQueryのスキーマは柔軟に変更できますが、その反面、テーブルにインサートするとき、意図しないスキーマ変更が発生します。
108+
109+
一例として、BigqueryAPIで以下のJobConfigで設定したときに、データだけでなく、スキーマまで上書きされる現象が起こります。
110+
111+
- `writeDisposition = WRITE_TRUNCATE` かつ
112+
- `autodetect = True`
113+
114+
詳しくは以下のリンクを参考しくてださい。
115+
116+
- [python - Google BigQuery WRITE_TRUNCATE erasing all data - Stack Overflow](https://stackoverflow.com/questions/55836849/google-bigquery-write-truncate-erasing-all-data)
117+
- [Job | BigQuery | Google Cloud](https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#jobconfigurationquery)
118+
119+
また、Terraformでカラムの型を定義する際、下記の例で示しているように、Bigqueryでaliasとして定義されたData Typeにもかかわらずに、自動的に右側の型に変換されることがあります。そして再度`terraform apply`を実行される際に、Terraform側で差分として認識されてしまいます。
120+
121+
`INT64`でなく、`INTEGER`
122+
`FLOAT64`でなく、`FLOAT`
123+
`DECIMEL`でなく、`NUMERIC`
124+
125+
## 対策
126+
127+
Terraformの`google_bigquery_table`リソースを利用して、データ型、制約、説明などのメタデータを検証したうえで適切に定義します。また、定義可能な型の範囲もプロジェクトごとにしっかり決めておくこともおすすめです。
128+
129+
```diff
130+
my_table.json
131+
[
132+
{
133+
"name": "id",
134+
- "type": "INT64",
135+
+ "type": "INTEGER",
136+
"description": "Unique identifier"
137+
},
138+
# その他のカラム
139+
]
140+
```
141+
142+
# 4. パーティショニングとクラスタリング
143+
144+
## 課題: パフォーマンス劣化、コスト増大
145+
146+
BigQueryのパーティショニングとクラスタリングは、クエリのパフォーマンスとコスト効率を向上させる重要な機能ですが、Terraformでの設定を誤ると、パフォーマンス劣化やコスト増大を招く可能性があります。
147+
148+
## 対策
149+
150+
クエリのパターンに合わせて、適切なパーティションキーとクラスタリングキーを選択し、パーティション分割の粒度を適切に設定し、不要なスキャンを減らします。
151+
152+
Terraformの`time_partitioning``clustering`引数を適切に設定し、パフォーマンスとコストを最適化します。順番も、先にパーティションを設定してから、クラスタリング。また、2025年4月時点、パーティションの上限が10000で、おおよそ27年分(10000÷365日)のデータを保存できます。
153+
154+
https://cloud.google.com/bigquery/quotas?hl=ja#partitioned_tables
155+
156+
```bash
157+
Terraform
158+
159+
resource "google_bigquery_table" "my_partitioned_table" {
160+
dataset_id = google_bigquery_dataset.my_dataset.dataset_id
161+
table_id = "my_partitioned_table"
162+
163+
time_partitioning {
164+
type = "DAY"
165+
field = "date"
166+
}
167+
168+
clustering {
169+
fields = ["name"]
170+
}
171+
}
172+
```
173+
174+
# 5. 権限管理とセキュリティ
175+
176+
## 課題: 意図しないデータアクセス、セキュリティリスク
177+
178+
BigQueryの権限管理は、データセキュリティ・データ活用の面において非常に重要です。とはいえ、必ずしもデータオーナーがコードベースで権限を管理できるわけではありません。Terraformでの初期設定をどこまですればいいか、非常に悩ましいことです。設定を誤ると、意図しないデータアクセスやセキュリティリスクを招く可能性があります。
179+
180+
## 対策
181+
182+
データオーナーがコードまでいじれないため、各テーブルに対して、[テーブルグループ](https://groups.google.com)を事前に設けることによって、データ閲覧者をあえてTerraformでのデータ管理から切り離します。
183+
184+
そして、Terraformの中で、`google_bigquery_dataset_access`または`google_bigquery_table_iam`、リソースを利用して、最小権限の原則に従って各テーブルグループに対して、対応するテーブルの閲覧権限のみを付与します。
185+
186+
初期設定として、テーブルグループの中で自動的に規定した各データオーナー部門のみを招待し、日頃の運用上、データオーナーがコードやリポジトリーではなく、グループ画面だけでデータ閲覧者の管理を行えるようになります。
187+
188+
```bash
189+
Terraform
190+
191+
resource "google_bigquery_dataset_access" "my_dataset_viewer" {
192+
dataset_id = google_bigquery_dataset.my_dataset.dataset_id
193+
194+
role = "roles/bigquery.dataViewer"
195+
196+
user_by_email = "dataset_id@my-domain.com"
197+
}
198+
```
199+
200+
# まとめ
201+
202+
Terraformは、BigQueryのデータ管理を効率化するための強力なツールですが、適切な設計と運用が不可欠です。本記事で紹介した5つのよくある落とし穴とサンプルコードを参考に、Terraformを活用してBigQueryのデータ管理を最適化し、データ品質とセキュリティを向上させましょう!
44.5 KB
Loading
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[ZoneTransfer]
2+
ZoneId=3
3+
HostUrl=https://mermaid.live/

source/images/20250407a/terraform_bigquery - コピー.png:Zone.Identifier

Whitespace-only changes.
49 KB
Loading
12.5 KB
Loading

0 commit comments

Comments
 (0)