07. Cloud SQL / Firestore
GCP の主要 DB は Cloud SQL(MySQL / PostgreSQL / SQL Server)と Firestore(NoSQL)。さらに大規模分散用に Spanner と Bigtable が用意されています。
どれを使うか
| Cloud SQL | Firestore | Spanner | |
|---|---|---|---|
| モデル | RDB | NoSQL ドキュメント | 分散 RDB |
| スケール | 単一インスタンス | 自動・無限 | 分散・無限 |
| 料金 | 常時稼働コスト | 従量制(読み書き) | 高い(最小 $700/月〜) |
| 用途 | 標準 Web/業務アプリ | モバイル・リアルタイム | 金融・大規模グローバル |
Cloud SQL (PostgreSQL)
resource "google_sql_database_instance" "main" {
name = "pg-myapp-prd"
database_version = "POSTGRES_16"
region = "asia-northeast1"
deletion_protection = true # 本番では必須
settings {
tier = "db-custom-2-7680" # vCPU 2 / RAM 7.5GB
availability_type = "REGIONAL" # ZONAL or REGIONAL (HA)
disk_type = "PD_SSD"
disk_size = 100
disk_autoresize = true
backup_configuration {
enabled = true
point_in_time_recovery_enabled = true
start_time = "16:00" # UTC = JST 01:00
backup_retention_settings {
retained_backups = 30
}
}
maintenance_window {
day = 7 # 日曜
hour = 17 # UTC 17:00 = JST 02:00
}
ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.main.id
enable_private_path_for_google_cloud_services = true
}
insights_config {
query_insights_enabled = true
record_application_tags = true
}
database_flags {
name = "log_min_duration_statement"
value = "1000"
}
}
}
resource "google_sql_database" "myapp" {
name = "myapp"
instance = google_sql_database_instance.main.name
}
resource "random_password" "db" {
length = 32
special = true
}
resource "google_sql_user" "app" {
name = "myapp"
instance = google_sql_database_instance.main.name
password = random_password.db.result
}
本番向け設定
- availability_type = "REGIONAL": 自動フェイルオーバー有効化
- deletion_protection = true:
terraform destroyを拒否 - backup + PITR: ポイントインタイムリカバリ
- private_network: VPC 内のみアクセス可(パブリック IP 無効化)
- CMEK 暗号化:
encryption_key_nameで KMS キーを指定
VPC との接続(Private Services Access)
# VPC に GCP サービス用の予約 IP 範囲を確保
resource "google_compute_global_address" "private_ip" {
name = "private-ip-cloud-sql"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = google_compute_network.main.id
}
# その範囲を Cloud SQL に peering で接続
resource "google_service_networking_connection" "main" {
network = google_compute_network.main.id
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [google_compute_global_address.private_ip.name]
}
Firestore
Firestore は project あたり 1 つの「Native モード」DB を持つ仕組み。ドキュメント/コレクション構造。
resource "google_firestore_database" "main" {
project = "myapp-prd"
name = "(default)" # デフォルト DB
location_id = "asia-northeast1"
type = "FIRESTORE_NATIVE"
point_in_time_recovery_enablement = "POINT_IN_TIME_RECOVERY_ENABLED"
delete_protection_state = "DELETE_PROTECTION_ENABLED"
}
# 追加 DB(複数 DB 対応)
resource "google_firestore_database" "analytics" {
project = "myapp-prd"
name = "analytics"
location_id = "asia-northeast1"
type = "FIRESTORE_NATIVE"
}
# インデックス
resource "google_firestore_index" "users_by_email_status" {
database = google_firestore_database.main.name
collection = "users"
fields {
field_path = "email"
order = "ASCENDING"
}
fields {
field_path = "status"
order = "ASCENDING"
}
fields {
field_path = "created_at"
order = "DESCENDING"
}
}
Cloud Spanner(概要)
「水平スケールする SQL DB」。料金の最小ラインが高い(処理単位 1 PU で月 ~$65、運用には 100 PU 程度推奨で月 $6500〜)ので、規模が小さいなら Cloud SQL の方が圧倒的に安い。
resource "google_spanner_instance" "main" {
config = "regional-asia-northeast1"
display_name = "myapp-spanner"
name = "myapp-spanner"
processing_units = 100 # 1 ノード = 1000 PU
}
resource "google_spanner_database" "main" {
instance = google_spanner_instance.main.name
name = "myapp"
ddl = [
"CREATE TABLE users (id STRING(36) NOT NULL, email STRING(255), created TIMESTAMP) PRIMARY KEY(id)",
]
deletion_protection = true
}
tip
新規アプリは Cloud SQL(PostgreSQL)から 始めるのが無難。NoSQL が本当に必要なら Firestore、グローバル分散が必要になった時に Spanner を検討。