概要 #
Cloud SQLはInstanceを作成しただけでは、実際に接続できるとは限りません。Public IPを有効にしても、Authorized Networkを設定しなければ外部からは接続できないためです。Instanceの状態がRUNNABLEであることと、接続できることは別の話です。
Terraformならこの一式をコードに残せる構成です。ここでは最小構成のPostgreSQL InstanceとDatabaseを作成します。実際に接続を試して、拒否されることまで確認します。
Terraformの基本操作は前提としています。
DB UserやPasswordの作成は扱いません。Authorized Networkの追加、Private IP、Application接続も扱いません。Secretの扱いを伴うため応用例に譲ります。
検証すること #
- Cloud SQL for PostgreSQL InstanceとDatabaseを作成できること
- Google Cloud CLIでInstance状態を確認できること
- Public IPへの接続がAuthorized Network未設定のため拒否されること(Instance状態の確認とは別)
- terraform destroyで削除できること
今回の構成 #
まず、何がどこに置かれるかです。InstanceはProject内のRegionリソースで、Databaseはその中に作られます。Public IPはInstanceに払い出されます。ただし接続を許可するAuthorized Networkは設定していません。
flowchart TB
subgraph GCP["Google Cloud"]
subgraph Project["Project"]
subgraph Region["asia-northeast1"]
subgraph Instance["Cloud SQL Instance: tf-example-postgres
PostgreSQL 15 / db-f1-micro / Zonal"]
DB["Database: appdb"]
PublicIP["Public IP
Authorized Network 未設定"]
end
end
end
end
Public IPへ接続を試すと、次のように拒否されます。
sequenceDiagram
actor User as 手元の端末
participant IP as Public IP(Cloud SQL)
User->>IP: TCP:5432へ接続試行
IP--x User: 接続タイムアウト
Note over User,IP: Authorized Networkが無く、到達経路がない
前提環境 #
- Google Cloud CLIとApplication Default Credentials(ADC)
- Terraform 1.11以降
- Billingが有効な検証用Google Cloud Project
- Cloud SQLを操作できるGoogleアカウント
- 検証時のバージョン:Terraform 1.14.3、google 7.43.0
使用するTerraformコード #
Cloud SQL Instance #
resource "google_sql_database_instance" "example" {
name = var.instance_name
region = var.region
database_version = var.database_version
deletion_protection = false
settings {
tier = var.tier
edition = "ENTERPRISE"
availability_type = "ZONAL"
disk_type = "PD_SSD"
disk_size = var.disk_size_gb
disk_autoresize = false
backup_configuration { enabled = false }
ip_configuration { ipv4_enabled = true }
}
}
デフォルトはPostgreSQL 15、db-f1-micro、Zonal、SSD 10GBです。学習用にBackup、Disk autoresize、Deletion protectionを無効にしています。
これらはコストと削除しやすさを優先した設定です。本番要件には適しません。本番ではHA、Backup、PITR、Deletion protectionなどを設計します。
ip_configurationはipv4_enabled = trueのみで、Authorized Networkは追加していません。Public IPは払い出されますが、任意のClientから直接接続できる構成ではありません。
Database #
resource "google_sql_database" "example" {
name = var.database_name
instance = google_sql_database_instance.example.name
}
Instance作成後にappdbを作成します。UserやPasswordは別Resourceで管理できますが、Secretの扱いを伴うため応用例で扱います。
設定と実行 #
cd Basic-Examples/13-cloud-sql-postgresql
cp terraform.tfvars.example terraform.tfvars
project_id = "your-project-id"
region = "asia-northeast1"
instance_name = "tf-example-postgres"
database_name = "appdb"
database_version = "POSTGRES_15"
tier = "db-f1-micro"
disk_size_gb = 10
terraform init
terraform fmt -check
terraform validate
terraform plan
terraform apply
API有効化・Instance・Databaseの3つが作成されます。Instance作成には10分ほどかかりました。
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
Outputs:
connection_name = "YOUR_PROJECT_ID:asia-northeast1:tf-example-postgres"
database_name = "appdb"
instance_name = "tf-example-postgres"
project_id = "YOUR_PROJECT_ID"
public_ip_address = "35.187.207.242"
GCP側で確認する #
gcloud sql instances describe \
"$(terraform output -raw instance_name)" \
--project="$(terraform output -raw project_id)"
state: RUNNABLE
databaseInstalledVersion: POSTGRES_15_18
settings:
tier: db-f1-micro
availabilityType: ZONAL
ipConfiguration:
ipv4Enabled: true
message: Configuring authorized network or using CloudSQL auth proxy or language
connectors is a prerequisite for connecting to Public IP. Please refer to the
documentation for more details https://cloud.google.com/sql/docs/mysql/authorize-networks.
ipConfiguration.messageにも、Public IPへ接続する前提条件としてAuthorized Networkの設定が必要だと明記されています。Databaseも確認します。
gcloud sql databases list \
--instance="$(terraform output -raw instance_name)" \
--project="$(terraform output -raw project_id)"
NAME CHARSET COLLATION
postgres UTF8 en_US.UTF8
appdb UTF8 en_US.UTF8
appdbと、Instanceに標準で存在するpostgresが確認できます。
接続できないことを確認する #
state: RUNNABLEは、Instanceが起動していることを示すだけです。実際にPublic IPへ接続できるかどうかは別に確認します。
nc -zv -w 5 "$(terraform output -raw public_ip_address)" 5432
nc: connect to 35.187.207.242 port 5432 (tcp) timed out: Operation now in progress
タイムアウトしました。Authorized Networkを設定していないため、これが意図した結果です。もし接続できてしまった場合は、設定漏れを疑います。
後片付け #
terraform destroy
Destroy complete! Resources: 3 destroyed.
Deletion protectionとBackupを無効化しています。削除するとDatabaseのDataは復元できません。検証用Dataだけを使用し、gcloud sql instances listでInstanceが消えたことも確認します。
まとめ #
- PostgreSQL VersionとMachine Tierを変数化できる
- InstanceとDatabaseの依存関係をTerraformで管理できる
- 学習用設定と本番向け設定の違いを理解できる
- Public IPが有効でも、Authorized Networkが無ければ接続できないことを実際に確認できる
- Cloud SQLは継続課金されるため迅速に後片付けする
参考資料 #
- Terraform: google_sql_database_instance
- Google Cloud: Cloud SQL for PostgreSQL
- Google Cloud: Authorized Networks
次回 #
次はCloud KMSのKeyRingとCryptoKeyを作成します。