TerraformでCloud SQLを消したくないのに消えそうになった
サマリ
- プロジェクト終了に伴いインフラ停止した際の知見
- リソース整理の過程で Cloud SQL のPrivate IP を外そうとしたら forces replacement が起きた
- もしapply すると Cloud SQL が再作成(=削除)される
- deletion_protection の設定は有効にしておくべき
なぜ Cloud SQL を消したくなかったのか
今回対象となった Cloud SQL は、本番環境で利用されていたデータベースでした。
プロダクト自体は終了フェーズに入っていましたが、データは削除してはいけないという前提がありました。
理由は、監査・証跡目的でのデータ保持が必要だったためです。
Cloud SQL を削除してしまうと、過去の状態を後から確認・説明する手段が失われてしまいます。
そのため今回の作業でやりたかったのは「削除」ではなく「停止」でした。
- サービスは停止する
- 不要なリソースは削除してコストを最小化する
- データは残す
- Cloud SQL は 停止(stop)まで にとどめる
この方針のもとで、Cloud SQL 自体は停止しつつ、付随する不要なリソースを整理することを考えていました。
やりたかったのは「プライベートIPを外す」だけ
Cloud SQL はコンソールから停止する予定でしたが、それに付随するネットワークリソースは不要になると判断していました。
アプリケーションリソースはすでに削除済みであり、外部からのアクセスも遮断した上で、可能な限りコストを下げたい状況だったので、
- VPC や Service Networking などの不要なリソースを削除する
- 可能であれば Cloud SQL の Private IP 接続も外す
Terraform 管理下ではip_configuration.private_network を削除すればよいだけに見え、
この時点では「設定を外すだけでインスタンス自体は残る」と考えていました。
resource "google_sql_database_instance" "xxxxx" {
name = "instance_name"
database_version = "database_version"
region = "region"
settings {
availability_type = "REGIONAL"
.... 省略
ip_configuration {
ipv4_enabled = true
# private_network を設定していた(今回ここを外そうとした)
}
}
}
Terraform plan から意図しない挙動に気づいた
terraform plan を確認したところ、次の差分が表示されました。
# module.common.google_sql_database_instance.postgres must be replaced
-/+ resource "google_sql_database_instance" "postgres" {
name = "prod-db-instance"
settings {
ip_configuration {
- private_network = "projects/***/global/networks/***" -> null
# forces replacement
}
}
}
表示されていたのは、
must be replaced# forces replacement
という内容で、「Private IP を外す変更が Cloud SQL インスタンスの再作成を前提にしている」という点に気づきました。
なので、作業を修正しPrivate IP を残して、Cloud SQL を停止することにしました。
誤って消してしまわないようにするには
通常のオペレーションで、planを確認せずにapplyすることはないと思います。
もし、今回の変更をそのまま terraform apply した場合、
- Cloud SQL インスタンスを削除
- 新しいインスタンスを再作成
という処理が実行される想定でした。そのような事故を防ぐためには、deletion_protection_enabledの設定が有効です。
resource "google_sql_database_instance" "xxxxx" {
name = "instance_name"
database_version = "database_version"
region = "region"
settings {
availability_type = "REGIONAL"
.... 省略
ip_configuration {
ipv4_enabled = true
# private_network を設定していた(今回ここを外そうとした)
}
# Cloud SQL インスタンス自体の削除を防ぐための設定
deletion_protection_enabled = true
}
}
この設定がされていれば、もしapplyを実行してしまってもCloud SQLの削除はできなくなるので、安心ですね。
Discussion