🦄

Cloud RunからCloud SQLへのプライベート接続を可能にする方法

に公開

はじめに

Google CloudでCloud RunからCloud SQLにセキュアに接続する際、VPCやプライベートIPアドレスの設定が必要です。本記事では、実際にTerraformで構築しながら、どのような設定が必要かを解説します。

GCPリソースの配置を理解する

GCPのマネージドサービスは、ネットワーク的に2つのカテゴリに分類されます。

1. VPC外で動作するサービス

特徴:

  • Google管理のインフラで動作
  • デフォルトではVPCに属さない
  • Direct VPC EgressでユーザーのVPCと接続

例: Cloud Run, Cloud Functions, App Engine

これらのサービスは完全にサーバーレスで、Googleが管理するインフラ上で動作します。ユーザーのVPCには属していないため、VPC内のリソースにアクセスするには明示的な設定が必要です。

2. Service Producer VPC内で動作するサービス

特徴:

  • Googleが管理する専用VPC内で動作
  • VPCピアリングでユーザーのVPCと接続

例: Cloud SQL, Cloud Memorystore, Cloud Filestore

これらのサービスは、Googleが管理する「Service Producer VPC」と呼ばれる専用VPC内で動作します。ユーザーのVPCとはVPCピアリングで接続されます。

ネットワーク構成の全体像

Cloud RunからCloud SQLへの接続には、以下の要素が必要です:

[Google管理インフラ]
    Cloud Run(VPC外)
        ↓ 
    Direct VPC Egress
        ↓
[ユーザーのVPC (10.0.0.0/24)]
        ↓ 
    VPCピアリング
        ↓
[Service Producer VPC]
    Cloud SQL (10.1.0.0/24)

この構成により、Cloud RunはVPC外からでもCloud SQLのプライベートIPにアクセスできるようになります。

Terraformで実装する

実際にTerraformでこの構成を構築してみましょう。

1. VPCとサブネットの作成

# VPC
resource "google_compute_network" "main" {
  name                    = "my-vpc"
  auto_create_subnetworks = false  # サブネットは手動作成
  mtu                     = 1460
}

# Cloud Run用のサブネット
resource "google_compute_subnetwork" "main" {
  name          = "my-subnet"
  region        = "asia-northeast1"
  network       = google_compute_network.main.id
  ip_cidr_range = "10.0.0.0/24"
}

2. Service Producer用のIP範囲予約

# Cloud SQLなどが使用するIP範囲を予約
resource "google_compute_global_address" "private_ip_range" {
  name          = "private-ip-range"
  purpose       = "VPC_PEERING"  # 用途を指定
  address_type  = "INTERNAL"
  prefix_length = 24
  address       = "10.1.0.0"  # サブネットと被らない範囲
  network       = google_compute_network.main.id
}

ポイント:

  • purpose = "VPC_PEERING"により、このIP範囲はService Producer専用になる
  • ユーザーのリソース(VMなど)はこの範囲を使用できない

3. VPCピアリング接続の確立

# Service Producer VPCとのピアリング
resource "google_service_networking_connection" "private_vpc_connection" {
  network                 = google_compute_network.main.id
  service                 = "servicenetworking.googleapis.com"
  reserved_peering_ranges = [google_compute_global_address.private_ip_range.name]
}

このリソースを作成すると、以下が自動的に行われます:

  1. VPCピアリング接続の確立

    • ユーザーのVPCとService Producer VPCの接続を作成
  2. VPCルートテーブルへのルート追加

    • 10.1.0.0/24 → vpc-peering のルートが自動追加される
  3. IP範囲の予約

    • 予約した10.1.0.0/24の範囲がService Producer専用として確保される
    • この時点ではまだCloud SQLは存在せず、IPも割り当てられていない

4. Cloud SQLの作成

resource "google_sql_database_instance" "postgres" {
  name             = "my-postgres"
  database_version = "POSTGRES_16"
  region          = "asia-northeast1"

  settings {
    tier    = "db-custom-1-3840"
    edition = "ENTERPRISE"
    
    ip_configuration {
      ipv4_enabled    = false  # 外部IPを無効化
      private_network = google_compute_network.main.id
      enable_private_path_for_google_cloud_services = true
    }
    
    database_flags {
      name  = "cloudsql.iam_authentication"
      value = "on"
    }
  }
  
  depends_on = [google_service_networking_connection.private_vpc_connection]
}

private_networkを指定すると、予約した10.1.0.0/24の範囲から自動的にIPが割り当てられます。

5. Cloud Runの設定

resource "google_cloud_run_v2_service" "app" {
  name     = "my-app"
  location = "asia-northeast1"

  template {
    service_account = google_service_account.cloud_run.email
    
    # VPCアクセス設定(Direct VPC Egress)
    vpc_access {
      network_interfaces {
        network    = google_compute_network.main.id
        subnetwork = google_compute_subnetwork.main.id
      }
      egress = "PRIVATE_RANGES_ONLY"  # プライベートIPのみ許可
    }

    containers {
      image = "gcr.io/my-project/my-app"
      
      env {
        name  = "DATABASE_HOST"
        value = google_sql_database_instance.postgres.private_ip_address
      }
      
      env {
        name  = "DATABASE_NAME"
        value = "postgres"
      }
    }
  }
}

vpc_access設定により:

  • Cloud Runコンテナから指定したVPCネットワークへアクセス可能になる
  • サブネット(10.0.0.0/24)からIPアドレスが自動割り当てされる
  • プライベートIP宛の通信がVPC経由でルーティングされる

ルーティングの仕組み

Direct VPC EgressとVPCピアリングの理解

重要: Direct VPC EgressとVPCピアリングは、どちらもVPCルートテーブルによるルーティングという同じ仕組みを使います。

GCPのVPCでは、VPC全体で単一の共通ルートテーブルを使用します。

つまり、VPC内のすべてのリソース(GCE VM、GKE、Cloud Run等)は、同じルートテーブルを参照してルーティング判定を行います。

それぞれの役割

設定 役割 ルーティングへの影響
Direct VPC Egress Cloud RunをVPCに「参加」させる VPCルートテーブルが使えるようになる
VPCピアリング VPC間を接続 VPCルートテーブルに新しいルートが追加される

VPCルートテーブルの確認

実際のルートテーブルを確認すると、すべてのルーティング情報が一箇所にまとまっていることがわかります:

# VPCのルートテーブルを確認
gcloud compute routes list \
  --filter="network:my-vpc" \
  --project=your-project-id

# 出力例:
# NAME                           NETWORK  DEST_RANGE   NEXT_HOP                           PRIORITY
# default-route-994013645858510  my-vpc   0.0.0.0/0    default-internet-gateway           1000
# default-route-r-3dc0e72dc2f3c49c my-vpc 10.0.0.0/24  my-vpc                             0
# peering-route-d7b72f40d71ac769 my-vpc   10.1.0.0/24  servicenetworking-googleapis-com   0

各ルートの説明:

ルート名 宛先範囲 Next-Hop 用途
default-route-[hash] 0.0.0.0/0 default-internet-gateway インターネット向けトラフィック
default-route-r-[hash] 10.0.0.0/24 my-vpc Cloud Runサブネット(ローカル)
peering-route-d[hash] 10.1.0.0/24 servicenetworking-googleapis-com Cloud SQL(VPCピアリング)

通信フローの詳細

1. アプリケーション層:
   connect("10.1.0.5:5432")  # Cloud SQLに接続

2. Cloud Runコンテナ:
   送信元IP: 10.0.0.47(サブネットから自動割当)
   宛先: 10.1.0.5(Cloud SQL)

3. VPCルートテーブル参照:
   宛先 10.1.0.5 を検索
   → 10.1.0.0/24 にマッチ
   → Next-Hop: vpc-peering-abc123

4. VPCピアリング経由:
   Service Producer VPCへ転送

5. Service Producer VPC:
   Cloud SQL(10.1.0.5)にパケット到達

重要なポイント:

  • ルーティングは「VPCルートテーブル」という1つのテーブルで行われる
  • Direct VPC Egressは「このテーブルへのアクセス権」を与える
  • VPCピアリングは「このテーブルに新しいルートを追加」する

最後に

本記事では、Cloud RunからCloud SQLへのプライベート接続を実現するために必要な、VPCとVPCピアリングの仕組みについて解説しました。
本記事が、皆さんのGoogle Cloudの理解の一助となれば幸いです。

Discussion