はじめに Link to heading

「WordPressを10サイト運用したい」

この要件に対して、どのようなインフラ構成を選びますか?

  • 各サイトごとに独立したサーバーを立てる?
  • 1台のサーバーにすべてを詰め込む?
  • マネージドサービスを使う?

この記事では、GCP上でWordPress マルチテナント環境(10サイト)を構築した実例を紹介します。単なる技術選定だけでなく、なぜその選択をしたのかという意思決定プロセスも含めて解説します。

この記事で扱う内容:

  1. 要件定義とアーキテクチャ選定理由
  2. システム全体構成
  3. コスト試算と最適化
  4. セキュリティ設計
  5. スケーラビリティと可用性

1. 要件定義 Link to heading

ビジネス要件 Link to heading

 1目的:
 2  - 10個のWordPressサイトをホスティング
 3  - 各サイトは独立したドメイン
 4  - 技術ブログ・情報サイトとして運用
 5
 6トラフィック想定:
 7  - 初期: 各サイト 1,000 PV/day
 8  - 成長後: 各サイト 10,000 PV/day
 9
10運用方針:
11  - Infrastructure as Code で管理
12  - 自動化重視
13  - コスト効率重視

技術要件 Link to heading

 1パフォーマンス:
 2  □ ページロード時間: 3秒以内
 3  □ TTFB (Time to First Byte): 500ms以内
 4  □ 同時アクセス: 各サイト100ユーザー
 5
 6可用性:
 7  □ 稼働率: 99.5%以上
 8  □ 自動復旧機能
 9  □ バックアップ: 日次
10
11セキュリティ:
12  □ SSL/TLS必須
13  □ DDoS対策
14  □ ファイアウォール
15  □ アクセス制御(IAP)
16
17運用性:
18  □ 監視・アラート
19  □ ログ集約
20  □ デプロイ自動化
21  □ スケーリング自動化

2. アーキテクチャ選定 Link to heading

検討した3つのパターン Link to heading

パターンA: シングルテナント(各サイトごとに独立サーバー) Link to heading

┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│ Site 1       │  │ Site 2       │  │ Site 10      │
│ VM + MySQL   │  │ VM + MySQL   │  │ VM + MySQL   │
└──────────────┘  └──────────────┘  └──────────────┘

メリット:

  • 完全な独立性
  • 障害の影響範囲が限定的

デメリット:

  • コストが高い(VM 10台 + MySQL 10インスタンス)
  • 運用管理コストが高い

コスト試算: 約 $500/月

判定: ❌ コストが高すぎる

パターンB: モノリシック(1台のサーバーにすべて) Link to heading

┌────────────────────────────┐
│  Single VM                 │
│  ┌──────────────────────┐  │
│  │ Site 1, 2, ... 10    │  │
│  │ MySQL                │  │
│  └──────────────────────┘  │
└────────────────────────────┘

メリット:

  • コストが最小
  • シンプルな構成

デメリット:

  • SPOFになる
  • スケーリングが困難
  • 障害時の影響範囲が大きい

コスト試算: 約 $50/月

判定: ❌ 可用性とスケーラビリティが不十分

パターンC: マルチテナント + オートスケーリング(採用) Link to heading

                    ┌─────────────────┐
                    │ Cloud CDN       │
                    │ (Cloudflare)    │
                    └────────┬────────┘
                             ▼
                    ┌─────────────────┐
                    │ Cloud Load      │
                    │ Balancer        │
                    └────────┬────────┘
                             ▼
        ┌────────────────────┴────────────────────┐
        │                                         │
   ┌────▼────┐  ┌──────────┐  ┌──────────┐      │
   │ VM 1    │  │ VM 2     │  │ VM 3     │      │
   │ (site*) │  │ (site*)  │  │ (site*)  │      │
   └────┬────┘  └────┬─────┘  └────┬─────┘      │
        │            │              │             │
        └────────────┴──────────────┴─────────────┘
                     │              │
          ┌──────────▼───┐  ┌──────▼──────────┐
          │ Cloud SQL    │  │ Cloud Filestore │
          │ (MySQL 8.0)  │  │ (NFS)           │
          └──────────────┘  └─────────────────┘

メリット:

  • 適度なコスト
  • オートスケーリング対応
  • マネージドサービス活用

デメリット:

  • 構成が複雑
  • 初期構築コストが高い

コスト試算: 約 $150/月

判定: ✅ バランスが良い


3. システム全体構成 Link to heading

コンポーネント一覧 Link to heading

コンポーネントGCPサービス役割冗長化
WebサーバーCompute EngineWordPress実行MIG (3-10台)
データベースCloud SQLMySQL 8.0マスター/スタンバイ可能
共有ストレージCloud FilestoreWordPressファイル共有NFSレプリケーション可能
ロードバランサCloud Load Balancingトラフィック分散グローバル冗長
CDNCloudflare静的コンテンツキャッシュグローバル分散
DNSCloud DNSドメイン管理Anycast
証明書Let’s EncryptSSL/TLS自動更新
シークレットSecret Managerパスワード管理-
監視Cloud Monitoringメトリクス収集-
ログCloud Loggingログ集約-

ネットワーク構成 Link to heading

VPC: prod-vpc (10.0.0.0/16)

Subnets:
  - web-subnet (10.0.1.0/24)     # Webサーバー用
  - mgmt-subnet (10.0.2.0/24)    # 管理用(将来)
  - db-subnet (10.168.0.0/20)    # Cloud SQL (自動作成)
  - nfs-subnet (10.0.3.0/24)     # Cloud Filestore

Private Service Connection:
  - Cloud SQL用プライベート接続
  - Cloud Filestore用プライベート接続

Firewall Rules:
  - allow-health-check (35.191.0.0/16 → 80, 443)
  - allow-iap-ssh (35.235.240.0/20 → 22)
  - deny-all-ingress (デフォルト拒否)

ストレージ構成 Link to heading

Cloud Filestore: /wordpress (1TB, BASIC_HDD)
  ├── site1/              # ai-jisso.tech
  │   ├── wp-config.php
  │   ├── wp-content/
  │   └── ...
  ├── site2/              # dev-ops.tech
  ├── site3/              # cloud-native.tech
  ├── ...
  └── site10/             # edge-computing.tech

Cloud SQL: prod-wordpress-db
  ├── wordpress_db_1      # site1用
  ├── wordpress_db_2      # site2用
  ├── ...
  └── wordpress_db_10     # site10用

ユーザー:
  ├── wp_user_1 → wordpress_db_1
  ├── wp_user_2 → wordpress_db_2
  ├── ...
  └── wp_user_10 → wordpress_db_10

Nginx仮想ホスト構成 Link to heading

各VMは10サイトすべてをホストします:

 1# /etc/nginx/sites-available/wordpress.conf
 2
 3# Site 1
 4server {
 5    listen 80;
 6    server_name ai-jisso.tech;
 7    root /var/www/wordpress/site1;
 8    # ... (共通設定)
 9}
10
11# Site 2
12server {
13    listen 80;
14    server_name dev-ops.tech;
15    root /var/www/wordpress/site2;
16    # ... (共通設定)
17}
18
19# ... (site3 ~ site10)

4. 技術選定理由 Link to heading

なぜCompute Engineか? Link to heading

候補:

  • Google Kubernetes Engine (GKE)
  • Cloud Run
  • Compute Engine

選定理由:

 1GKE:
 2  メリット: コンテナオーケストレーション、宣言的管理
 3  デメリット:
 4    - オーバーエンジニアリング(10サイトには大きすぎる)
 5    - 学習コストが高い
 6    - コストが高い(ノードプール + コントロールプレーン)
 7
 8Cloud Run:
 9  メリット: サーバーレス、完全マネージド
10  デメリット:
11    - ステートフル (WordPress) との相性が悪い
12    - NFSマウントの制約
13    - MySQL接続のコネクションプール管理が複雑
14
15Compute Engine: 
16  メリット:
17    - シンプル
18    - NFSマウントが容易
19    - オートスケーリング対応
20    - コストが適切
21  デメリット:
22    - OS管理が必要(Ansibleで自動化)

なぜCloud SQLか? Link to heading

候補:

  • 自前のMySQL on Compute Engine
  • Cloud SQL

選定理由:

 1自前MySQL:
 2  メリット: コストが安い、完全な制御
 3  デメリット:
 4    - バックアップ管理が必要
 5    - 高可用性構成が複雑
 6    - セキュリティパッチ適用が手動
 7
 8Cloud SQL: 
 9  メリット:
10    - 自動バックアップ
11    - 高可用性オプション
12    - 自動パッチ適用
13    - Private IP接続
14    - ポイントインタイムリカバリ
15  デメリット:
16    - コストがやや高い(→ 小さいインスタンスで対応)

なぜCloud Filestoreか? Link to heading

候補:

  • Cloud Storage (GCS)
  • Persistent Disk
  • Cloud Filestore

選定理由:

 1Cloud Storage:
 2  メリット: 安価、無制限容量
 3  デメリット:
 4    - WordPressとの互換性問題
 5    - FUSE経由のマウントでパフォーマンス低下
 6    - ファイルロックの制約
 7
 8Persistent Disk:
 9  メリット: 高パフォーマンス
10  デメリット:
11    - 1つのVMにしかアタッチできない
12    - マルチVMでの共有が不可能
13
14Cloud Filestore: 
15  メリット:
16    - NFSプロトコル(標準的)
17    - 複数VMから同時マウント可能
18    - WordPressとの完全互換性
19    - 高パフォーマンス
20  デメリット:
21    - コストがやや高い(→ BASIC_HDDで対応)

なぜCloudflareか? Link to heading

候補:

  • Cloud CDN
  • Cloudflare

選定理由:

 1Cloud CDN:
 2  メリット: GCPネイティブ、設定が簡単
 3  デメリット:
 4    - DDoS対策が限定的
 5    - WAF機能がない(Cloud Armorが別途必要)
 6    - DNS管理が別サービス
 7
 8Cloudflare: 
 9  メリット:
10    - 無料プランで十分な機能
11    - DDoS対策が標準装備
12    - WAF機能
13    - DNS管理も一元化
14    - SSL証明書自動管理
15  デメリット:
16    - GCPの外部サービス

5. コスト試算 Link to heading

月額コスト内訳(本番環境) Link to heading

項目スペック月額料金備考
Compute Engine
- VM (e2-micro × 3台)2vCPU, 1GB RAM$21最小構成
- Persistent Disk (10GB × 3台)Standard$1OS用
Cloud SQL
- インスタンス (db-f1-micro)1vCPU, 0.6GB RAM$15最小構成
- ストレージ (10GB)SSD$2
- バックアップ (10GB)$17日保持
Cloud Filestore
- 1TB BASIC_HDD$51最小容量
Cloud Load Balancing
- フォワーディングルール$18
- データ転送 (100GB)$8
Cloud Logging
- ログ保存 (10GB)$1
Cloud Monitoring
- メトリクス$2
Secret Manager
- 10シークレット$0.06ほぼ無料
Cloudflare
- Free プラン$0無料
合計$120

コスト最適化のポイント Link to heading

1. Computeインスタンスの選択 Link to heading

 1# 最小構成(採用)
 2machine_type: e2-micro
 3cost: $7/月/台
 4
 5# 中間構成
 6machine_type: e2-small
 7cost: $14/月/台
 8
 9# 高性能構成
10machine_type: e2-medium
11cost: $28/月/台

判断: e2-microで開始し、必要に応じてスケールアップ

2. Cloud SQLのティア選択 Link to heading

 1# 最小構成(採用)
 2tier: db-f1-micro
 3cost: $15/月
 4
 5# 推奨構成
 6tier: db-g1-small
 7cost: $35/月
 8
 9# 本番推奨
10tier: db-custom-2-7680
11cost: $85/月

判断: 初期はdb-f1-micro、トラフィック増加後にスケールアップ

3. Cloud Filestoreのティア選択 Link to heading

1# 最小容量(採用)
2tier: BASIC_HDD
3capacity: 1TB
4cost: $51/月
5
6# 高性能
7tier: BASIC_SSD
8capacity: 1TB
9cost: $204/月

判断: BASIC_HDDで十分なパフォーマンス

4. コミットメント割引 Link to heading

1# 1年コミットメント
2割引率: 25%
3節約額: $30/月
4
5# 3年コミットメント
6割引率: 52%
7節約額: $62/月

トラフィック成長時のコスト予測:

トラフィックVM台数月額コスト備考
10,000 PV/day3台$120初期構成
50,000 PV/day5台$140スケールアップ
100,000 PV/day7台$160
500,000 PV/day10台$190最大構成

6. セキュリティ設計 Link to heading

多層防御アーキテクチャ Link to heading

Layer 7: Application (WordPress)
  □ プラグインの脆弱性管理
  □ 定期アップデート
  □ セキュリティプラグイン

Layer 6: CDN/WAF (Cloudflare)
  □ DDoS対策
  □ WAFルール
  □ レート制限

Layer 5: Load Balancer (Cloud LB)
  □ SSL/TLS終端
  □ ヘッダー検証

Layer 4: Network (VPC)
  □ ファイアウォールルール
  □ プライベートIP
  □ サブネット分離

Layer 3: Compute (VM)
  □ OS自動パッチ
  □ 最小権限の原則
  □ IAP SSH

Layer 2: Data (Cloud SQL)
  □ 暗号化(保存時・転送時)
  □ プライベートIP
  □ 自動バックアップ

Layer 1: Identity (IAM)
  □ Service Account
  □ 最小権限ロール
  □ Workload Identity

ファイアウォールルール Link to heading

 1# Health Check許可
 2resource "google_compute_firewall" "allow_health_check" {
 3  name    = "allow-health-check"
 4  network = google_compute_network.vpc.name
 5
 6  allow {
 7    protocol = "tcp"
 8    ports    = ["80", "443"]
 9  }
10
11  source_ranges = [
12    "35.191.0.0/16",    # Cloud Load Balancing
13    "130.211.0.0/22"    # Legacy health checks
14  ]
15
16  target_tags = ["web-server"]
17}
18
19# IAP SSH許可
20resource "google_compute_firewall" "allow_iap_ssh" {
21  name    = "allow-iap-ssh"
22  network = google_compute_network.vpc.name
23
24  allow {
25    protocol = "tcp"
26    ports    = ["22"]
27  }
28
29  source_ranges = ["35.235.240.0/20"]  # IAP
30  target_tags   = ["web-server"]
31}
32
33# デフォルト拒否
34resource "google_compute_firewall" "deny_all" {
35  name     = "deny-all-ingress"
36  network  = google_compute_network.vpc.name
37  priority = 65534
38
39  deny {
40    protocol = "all"
41  }
42
43  source_ranges = ["0.0.0.0/0"]
44}

IAM設計 Link to heading

 1# Webサーバー用Service Account
 2resource "google_service_account" "web_server" {
 3  account_id   = "${var.env}-web-server"
 4  display_name = "Web Server Service Account"
 5}
 6
 7# 必要最小限のロール
 8resource "google_project_iam_member" "web_server_roles" {
 9  for_each = toset([
10    "roles/logging.logWriter",           # ログ書き込み
11    "roles/monitoring.metricWriter",     # メトリクス書き込み
12    "roles/cloudsql.client",             # Cloud SQL接続
13    "roles/secretmanager.secretAccessor" # Secret Manager読み取り
14  ])
15
16  project = var.project_id
17  role    = each.key
18  member  = "serviceAccount:${google_service_account.web_server.email}"
19}

7. スケーラビリティと可用性 Link to heading

オートスケーリング設定 Link to heading

 1resource "google_compute_region_autoscaler" "web" {
 2  name   = "${var.env}-web-autoscaler"
 3  region = var.region
 4  target = google_compute_region_instance_group_manager.web.id
 5
 6  autoscaling_policy {
 7    min_replicas    = 3
 8    max_replicas    = 10
 9    cooldown_period = 60
10
11    cpu_utilization {
12      target = 0.6  # CPU使用率60%で スケールアウト
13    }
14
15    load_balancing_utilization {
16      target = 0.8  # 負荷分散使用率80%でスケールアウト
17    }
18  }
19}

高可用性構成 Link to heading

 1Compute Engine:
 2  □ Managed Instance Group
 3  □ 複数ゾーンに分散配置可能
 4  □ 自動復旧(ヘルスチェック失敗時)
 5  □ ローリングアップデート対応
 6
 7Cloud SQL:
 8  □ 高可用性構成オプション(マスター/スタンバイ)
 9  □ 自動フェイルオーバー
10  □ ポイントインタイムリカバリ
11  □ 自動バックアップ
12
13Cloud Filestore:
14  □ ゾーンレベルの冗長性
15  □ 自動スナップショット
16
17Cloud Load Balancer:
18  □ グローバル冗長
19  □ 自動フェイルオーバー

ヘルスチェック設定 Link to heading

 1resource "google_compute_health_check" "web" {
 2  name = "${var.env}-web-health-check"
 3
 4  http_health_check {
 5    port         = 80
 6    request_path = "/health"  # ヘルスチェック用エンドポイント
 7  }
 8
 9  check_interval_sec  = 10
10  timeout_sec         = 5
11  healthy_threshold   = 2
12  unhealthy_threshold = 3
13}

8. 監視とアラート Link to heading

監視メトリクス Link to heading

 1Compute Engine:
 2  - CPU使用率
 3  - メモリ使用率
 4  - ディスクI/O
 5  - ネットワークトラフィック
 6
 7Cloud SQL:
 8  - クエリ実行時間
 9  - 接続数
10  - レプリケーション遅延(高可用性時)
11  - ストレージ使用率
12
13Cloud Filestore:
14  - IOPS
15  - スループット
16  - ストレージ使用率
17
18Application:
19  - レスポンスタイム
20  - エラー率
21  - リクエスト数

アラートポリシー Link to heading

 1resource "google_monitoring_alert_policy" "cpu_high" {
 2  display_name = "${var.env} - High CPU Usage"
 3
 4  conditions {
 5    display_name = "CPU usage above 80%"
 6
 7    condition_threshold {
 8      filter          = "resource.type = \"gce_instance\""
 9      comparison      = "COMPARISON_GT"
10      threshold_value = 0.8
11      duration        = "300s"
12
13      aggregations {
14        alignment_period   = "60s"
15        per_series_aligner = "ALIGN_MEAN"
16      }
17    }
18  }
19
20  notification_channels = [google_monitoring_notification_channel.email.name]
21}

9. デプロイフロー Link to heading

初回構築 Link to heading

 1# 1. Terraformでインフラ構築
 2cd terraform/environments/prod
 3terraform init
 4terraform plan
 5terraform apply
 6
 7# 2. Ansibleでアプリケーションデプロイ
 8cd ../../ansible
 9ansible-playbook -i inventory/gcp.yml playbooks/deploy-wordpress.yml \
10  -e "db_host=10.168.0.2" \
11  -e "nfs_ip=10.0.3.2" \
12  -e "nfs_path=/wordpress"
13
14# 3. 各サイトのWordPressインストール
15for i in {1..10}; do
16  gcloud compute ssh prod-web-$(hostname) \
17    --zone=asia-northeast1-a \
18    --tunnel-through-iap \
19    --command="sudo /usr/local/bin/setup-wordpress-site.sh $i domain$i.tech 'Site $i'"
20done

更新デプロイ Link to heading

1# アプリケーション設定の更新
2cd ansible
3ansible-playbook -i inventory/gcp.yml playbooks/deploy-wordpress.yml \
4  --tags nginx  # Nginxだけ更新
5
6# インフラ設定の更新
7cd terraform/environments/prod
8terraform apply

まとめ Link to heading

アーキテクチャ選定の判断基準 Link to heading

要素重視度選択結果
コスト⭐⭐⭐⭐マネージドサービスとVMのバランス
パフォーマンス⭐⭐⭐NFSとCDNで対応
スケーラビリティ⭐⭐⭐⭐オートスケーリング
運用性⭐⭐⭐⭐⭐IaCで完全自動化
セキュリティ⭐⭐⭐⭐⭐多層防御

成功のポイント Link to heading

  1. マネージドサービスの活用

    • Cloud SQL: バックアップ・パッチ自動化
    • Cloud Filestore: NFSの簡単な共有
    • Cloud Load Balancer: グローバル冗長
  2. Infrastructure as Code

    • Terraform: インフラ層
    • Ansible: 構成管理層
    • 完全な再現性
  3. コスト最適化

    • 最小構成から開始
    • オートスケーリングで必要な時だけ拡張
    • コミットメント割引の活用
  4. セキュリティファースト

    • プライベートIP接続
    • 最小権限の原則
    • 多層防御

今後の改善予定 Link to heading

 1Phase 2:
 2  □ Cloud CDN統合(現在はCloudflare)
 3  □ Cloud Armorの導入(WAF)
 4  □ 高可用性構成(Cloud SQL)
 5
 6Phase 3:
 7  □ CI/CDパイプライン構築
 8  □ Blue-Greenデプロイ
 9  □ カナリアリリース
10
11Phase 4:
12  □ マルチリージョン展開
13  □ Wazuhによるセキュリティ監視
14  □ コンテナ化の検討

参考リンク Link to heading


この記事のコード Link to heading

GitHub: infra-ai-agent

Terraform:

Ansible:


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