Cloud SQLのリードレプリカにパスワードポリシーを設定してしまった場合の対処法
Cloud SQLでMySQLサーバを使用していたあるとき
インスタンス状態に関する問題という項目で「パスワードポリシーがない」というチェックがあるタイミングからつくようになりました
これはインスタンス(またはユーザー)に対して設定できる項目で、パスワードの条件を指定することができる機能です。パスワード自体はパスワードマネージャーで生成したそこそこ長いパスワードを利用していたので変な設定にしなければ普通に追加していいな、と思いTerraformのインスタンス設定にパスワードポリシーを追加しました
resource "google_sql_database_instance" "mysql_instance" {
# ...中略
settings {
# ...中略
password_validation_policy {
min_length = 8
# ...中略
}
# そのほか設定
}
}
そしてレプリカにも 設定した(先に言うと設定してはいけません!!!!)
resource "google_sql_database_instance" "mysql_instance_replica" {
# ...中略
settings {
# ...中略
password_validation_policy {
min_length = 8
# ...中略
}
# そのほか設定
}
}
そしてデプロイ
もう一回言うが、これは設定してはいけない。というより、レプリカにはパスワードポリシーを設定してはいけない。というより本来設定できない。 が、なぜか terraform apply が成功してしまった
そして次のデプロイを行おうとすると以下のようなエラーが出た
with google_sql_database_instance.mysql_instance_replica,
on cloud_sql.tf line 64, in resource "google_sql_database_instance" "mysql_instance_replica":
64: resource "google_sql_database_instance" "mysql_instance_replica" {
そう、パスワードポリシーの設定はレプリカにはできない。できないはずなのになぜか初回だけ通ってしまうバグがある様子だった(GCP側のバグっぽい)
で、今回はこれの対応。結論から言うと半ば絶望的である
まだなんとかなるかもしれないケース
ひとまずだがこのパスワードポリシーを確認する。コンソールでは見えない(レプリカはそもそも設定項目自体が見えなくなっている)が、以下のコマンドで確認できる。instance_name は適宜インスタンス名を当ててコマンドを叩く
$ gcloud sql instances describe instance_name --format="value(settings.passwordValidationPolicy)"
これを見ると確かに設定されている。この設定を排除できればおそらくまだ助かる。というわけで以下のコマンドを叩いてみる
備考:https://cloud.google.com/sdk/gcloud/reference/sql/instances/patch
$ gcloud sql instances patch instance_name --clear-password-policy
この --clear-password-policy
フラグは上記のドキュメント曰くPostgresでしか使えないらしいが、なぜかMySQLでも使える。そしてこれを利用するとパスワードポリシーを無効化できる
これでデプロイして通れば解決である。私の場合解決しなかったが
状態の再確認
試しにレプリカをもう一つ(コンソール上から)作って同様に describe コマンドを叩くと、そもそもsettings.passwordValidationPolicy
自体がないことが確認された。つまり無効化ではなく削除が必要なのである
が、APIにはalpha/beta含めてその項目はない。つまり終わりである(本当に
対応
というわけで対処法を考えるしかない……というか、おそらくインスタンスを再作成するしかない。インスタンスの作成は時間がかかる上、マスターのテーブル・データ量によっては恐ろしく時間がかかることが想定されるため一応いくつか方法をあげる
そこまで時間がかからない(数時間以内で解決する場合)
メンテモード等を利用してアクセスできない環境を作り、そのタイミングでインスタンスを手動で削除→再作成するという方法である
またレプリカのアクセスが内部からのみとか、そういうケースではそれでいいだろう。本番環境等ではおすすめしないが、深夜対応等で可能ならこれでも問題はないと思われる
問題点としてレプリカの作成時間は正確には読めないため、シビアな環境ではちょっと厳しいかもしれない
時間がかかりそうな場合
重めのサービスの場合はこっち。新レプリカを作成し、レプリカの接続先を新レプリカに切り替え、その後で旧レプリカを削除するという方法である
レプリカの作成自体はコンソールから行い、terraform state rm
で旧レプリカの管理を外し、terraform import
で新レプリカを取り込めば設定を間違えてない限り再デプロイで勝手に新しいレプリカに繋がり始めるし、terraformのエラーも回避しやすい(その間デプロイできないという問題があるが)
この場合時間経過が許容できるため余裕を持って作業すると良い。結構ビビるからねこういうトラブル
余談
そういえばコンソールから更新してなかったなと思ってやってみたところ同様のエラーが出た
とりあえず報告したので対応されるか自力で対応する必要があるか……
追記
サポートに問い合わせたところ対応してもらえた(現在対応途中。終わったらまた追記する
上記の自己修復はしなくても済みそうである
再追記
実質的には1営業日ぐらいで対応してもらえた
完全にサポート経由でしか直せない様子。おそらくエラーの報告も上がっているはずなのでそのうち修正されそうだが
同じ穴にはまる人がいないことを望む
Discussion