↓メインコンテンツへスキップ
  1. Blogs/

TerraformでCloud SQL for PostgreSQLを作成してみた

2 分
Terraform GoogleCloud PostgreSQL
0222-nnn
著者
0222-nnn
猫が好き
目次
Terraform-GoogleCloud - この記事は連載の一部です
パート 14: この記事

概要
#

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は継続課金されるため迅速に後片付けする

参考資料
#

次回
#

次はCloud KMSのKeyRingとCryptoKeyを作成します。

Terraform-GoogleCloud - この記事は連載の一部です
パート 14: この記事

関連記事

Terraform StateをCloud Storage Remote Backendへ移行してみた
2 分
Terraform GoogleCloud CloudStorage
TerraformからGoogle Cloudへ接続してProject情報を取得してみた
3 分
Terraform GoogleCloud
TerraformでArtifact RegistryのDocker Repositoryを作成してみた
2 分
Terraform GoogleCloud Docker
TerraformでArtifact RegistryのコンテナをCloud Runへデプロイしてみた
2 分
Terraform GoogleCloud CloudRun ArtifactRegistry
TerraformでBigQuery DatasetとTableを作成してみた
2 分
Terraform GoogleCloud
TerraformでCloud KMSのKeyRingとCryptoKeyを作成してみた
2 分
Terraform GoogleCloud