はじめに Link to heading

「とりあえず動けばいい」

この思考が、2時間の無駄な試行錯誤を生み出しました。

GCP上でWordPress マルチテナント環境を構築していた際、Cloud SQLのSSL証明書エラーに遭遇しました。その時に取った「アプリケーション層での対症療法」というアプローチが、いかに間違っていたか。そして、なぜそのような判断をしてしまったのか。

この記事では、失敗の過程を包み隠さず共有し、同じミスを繰り返さないための教訓を整理します。


1. 問題の発生経緯 Link to heading

最初のエラーメッセージ Link to heading

WordPressのインストール中、こんなエラーに遭遇しました:

Error establishing a database connection

詳細を確認すると:

mysqli_real_connect(): SSL operation failed with code 1. OpenSSL Error messages:
error:0A000126:SSL routines::unexpected eof while reading

その時の私の思考:

  • 「SSL証明書の問題だな」
  • 「WordPressがCloud SQLのSSL証明書を読み込めていない」
  • 「→ アプリケーション側で証明書を設定すれば解決するはず」

この判断が、すべての間違いの始まりでした。


2. 判断ミス1: カスタムdb.phpによる対症療法 Link to heading

取ったアプローチ(間違い) Link to heading

私は wp-content/db.php というカスタムMySQLドライバを作成しました:

 1<?php
 2// カスタムMySQLドライバ - SSL証明書を設定
 3class wpdb extends wpdb {
 4    public function db_connect($allow_bail = true) {
 5        $this->dbh = new mysqli(
 6            DB_HOST,
 7            DB_USER,
 8            DB_PASSWORD,
 9            DB_NAME,
10            3306,
11            null
12        );
13
14        // SSL証明書設定
15        $this->dbh->ssl_set(
16            '/var/www/certs/client-key.pem',
17            '/var/www/certs/client-cert.pem',
18            '/var/www/certs/server-ca.pem',
19            null,
20            null
21        );
22
23        return $this->dbh->real_connect(
24            DB_HOST,
25            DB_USER,
26            DB_PASSWORD,
27            DB_NAME,
28            3306,
29            null,
30            MYSQLI_CLIENT_SSL
31        );
32    }
33}

この判断の何が問題だったのか Link to heading

問題1: アプリケーション層で解決しようとした Link to heading

  • 根本原因: Cloud SQLのデフォルト設定が require_ssl = true
  • 私の対応: アプリケーション側でSSL証明書を設定
  • 正しい対応: Terraformで require_ssl = false に設定すべきだった
1# 正しいアプローチ(Terraform)
2resource "google_sql_database_instance" "wordpress" {
3  settings {
4    ip_configuration {
5      require_ssl = false  # ← これだけで解決
6    }
7  }
8}

問題2: IaC原則違反 Link to heading

  • カスタムファイル(db.php)を手動で配置
  • Ansible管理外のファイル
  • 他のサーバーへの展開時に再現性がない
  • Git管理されていない

問題3: WordPressコアの動作を変更 Link to heading

  • wp-content/db.php はWordPressの「ドロップインファイル」
  • WordPressのデータベース接続ロジック全体を上書き
  • 将来のWordPressアップデートで互換性問題のリスク

3. 判断ミス2: Terraformでの根本対応を後回しにした Link to heading

なぜ後回しにしたのか Link to heading

私の思考プロセス:

  1. 「カスタムdb.phpで動いた!」
  2. 「とりあえずWordPressのインストールを進めよう」
  3. 「インフラ設定の変更は後でいいや」

この「とりあえず動けばいい」思考が致命的でした。

後回しにした結果 Link to heading

  1. 新しいインスタンスで同じエラー

    • Terraform applyでインスタンスが再作成
    • カスタムdb.phpが存在しない
    • 再度同じエラーに遭遇
  2. デバッグの混乱

    • 「なぜ動いていたのに動かなくなった?」
    • カスタムdb.phpの存在を忘れていた
    • NFSマウントされたファイルの把握が困難
  3. 最終的にカスタムdb.phpを削除

    • Terraformで require_ssl = false に変更
    • カスタムdb.phpを削除
    • あっさり解決

4. 時系列でみる判断の分岐点 Link to heading

各ポイントでの「取るべきだった行動」 Link to heading

時点実際の行動取るべきだった行動
エラー発生アプリ層で解決を試みるインフラ設定を確認
カスタムdb.php作成「動いた!」と満足根本原因を調査
一時的に動作次のタスクに進むTerraform修正を完了
インスタンス再作成「なぜ動かない?」と混乱-
2時間後Terraform修正最初からこうすべきだった

5. 根本原因分析: なぜ判断を誤ったのか Link to heading

原因1: Cloud SQLのデフォルト設定への理解不足 Link to heading

知らなかったこと:

  • Cloud SQLのデフォルトは require_ssl = true
  • プライベートIP接続でもSSL要件は有効
  • SSL証明書は手動で発行・配布する必要がある

学んだこと:

1# Cloud SQLの設定確認コマンド
2gcloud sql instances describe INSTANCE_NAME \
3  --format="value(settings.ipConfiguration.requireSsl)"

原因2: エラーメッセージの表面的な読み取り Link to heading

エラーメッセージ:

SSL operation failed

私の解釈: 「証明書が足りない」 正しい解釈: 「そもそもSSL接続が必要ない環境でSSLを要求されている」

原因3: アプリケーション層で解決しようとするバイアス Link to heading

私の背景:

  • アプリケーションエンジニア出身
  • インフラ設定よりコード修正に慣れている
  • 「コードで解決できる」という思い込み

バイアスの罠:

  • アプリ層で解決 = 「すぐできる」「簡単」
  • インフラ層の変更 = 「面倒」「怖い」「影響範囲が大きい」

現実:

対応実装時間デバッグ時間保守性
カスタムdb.php30分2時間
Terraform修正5分0分

原因4: IaC原則の理解不足 Link to heading

違反したIaC原則:

  1. すべてをコードで管理

    • 違反: カスタムdb.phpを手動配置
    • 正: Terraformで設定変更
  2. 冪等性

    • 違反: 手動ファイル配置は再現性がない
    • 正: terraform applyは何度実行しても同じ結果
  3. 不変インフラ

    • 違反: 既存サーバーにファイル追加
    • 正: 設定変更後にインスタンス再作成

6. 再発防止策: 同様の事象が起きた時のチェックリスト Link to heading

エラー発生時の思考フロー Link to heading

□ Step 1: エラーの発生層を特定
  - インフラ層(ネットワーク、DB設定、認証)
  - ミドルウェア層(Nginx、PHP、MySQL)
  - アプリケーション層(WordPress、プラグイン)

□ Step 2: デフォルト設定を確認
  - 「デフォルトではどうなっているか?」
  - 「設定を変更したか?」
  - 「ドキュメントの推奨設定は?」

□ Step 3: 対応方法の検討
  - 根本対応か対症療法か?
  - IaC原則に従っているか?
  - 将来の運用コストは?

□ Step 4: 実装前の自問自答
  - 「この対応は再現可能か?」
  - 「他のサーバーでも動くか?」
  - 「1年後も保守できるか?」

Cloud SQL固有のチェックリスト Link to heading

□ プライベートIP接続かパブリックIP接続か?
  - プライベートIPならSSL不要なケースが多い

□ require_ssl設定を確認
  gcloud sql instances describe INSTANCE_NAME

□ アプリケーションから接続テスト
  mysql -h DB_HOST -u DB_USER -p

□ SSL証明書の有効期限確認(SSL使う場合)
  gcloud sql ssl-certs list --instance=INSTANCE_NAME

7. 学んだこと・読者へのメッセージ Link to heading

失敗から得た3つの教訓 Link to heading

教訓1: 「動けばいい」は技術的負債の始まり Link to heading

一時的に動作することと、正しく動作することは別物です。

  • カスタムdb.phpは「動いた」
  • しかし、保守不可能で再現性もない
  • 結局、後で2時間かけて正しく直すことに

正しいアプローチ:

  1. エラーの根本原因を特定
  2. インフラ層の設定を修正
  3. 再現可能な形で実装

教訓2: IaC原則は「面倒な作業」ではなく「時間短縮」 Link to heading

「Terraform修正は面倒だから後で…」という思考が、結果的に時間を浪費しました。

比較: 最初からTerraform修正していた場合

アプローチ実装デバッグ合計
カスタムdb.php → Terraform30分120分150分
最初からTerraform5分0分5分

時間差: 145分(2時間25分)

教訓3: エラーメッセージは「何が足りないか」ではなく「何が間違っているか」を示す Link to heading

SSL operation failed

このメッセージを「証明書が足りない」と解釈したのが間違いでした。

正しい解釈:

  • 「SSL接続を要求されているが、それは必要か?」
  • 「プライベートIP接続でSSLは必須ではない」
  • 「→ インフラ設定を見直すべき」

読者へのメッセージ Link to heading

失敗は避けられません。重要なのは、失敗から学び、同じミスを繰り返さないことです。

この記事で共有した判断ミスは、決して特殊なケースではありません。

  • 「とりあえず動けばいい」
  • 「後で直せばいい」
  • 「アプリで解決できるはず」

これらの思考パターンは、誰にでも起こりうるものです。

大切なこと:

  1. 失敗を記録する
  2. なぜその判断をしたのか分析する
  3. 次回同じ状況でどう判断すべきか整理する

あなたが同じようなエラーに遭遇した時、この記事が判断の助けになれば幸いです。


参考リンク Link to heading


この記事のコード Link to heading

実際のTerraform設定:

 1# terraform/modules/database/main.tf
 2resource "google_sql_database_instance" "wordpress" {
 3  name             = "${var.env}-wordpress-db"
 4  database_version = "MYSQL_8_0"
 5  region           = var.region
 6
 7  settings {
 8    ip_configuration {
 9      ipv4_enabled    = false  # パブリックIPは無効
10      private_network = var.network_id
11      require_ssl     = false  # ← これが重要!
12    }
13  }
14}

GitHub: infra-ai-agent


まとめ Link to heading

  • ❌ カスタムdb.phpによる対症療法は間違い
  • ✅ Terraformで require_ssl = false に設定するのが正解
  • ⏱️ 正しいアプローチなら5分で解決(実際は2時間浪費)
  • 📚 IaC原則を守ることが、結果的に時間短縮になる
  • 🎯 エラーメッセージの真意を読み取る訓練が必要

次回予告: 「WordPress環境構築で遭遇した5つのハマりポイントと解決策」では、今回のSSL問題以外にも遭遇した具体的なトラブル事例を共有します。


著者について: インフラエンジニアリングを学びながらGCP上でマルチテナントWordPress環境を構築。失敗から学ぶことを大切にしています。

この記事が役に立ったら: GitHub Starをいただけると嬉しいです! infra-ai-agent