★★ 中級

03. VPC とネットワーク

GCP の VPC は AWS と大きく違って 「グローバルリソース」。1 つの VPC が全リージョンにまたがり、Subnet がリージョン単位で配置されます。Firewall も「VPC 全体に対するルール」と発想が異なる。

AWS との対応と違い

GCPAWS違い
VPCVPCGCP はグローバル。CIDR は subnet 単位
SubnetSubnetリージョン単位(AZ 単位ではない)
FirewallSecurity Group + NACLVPC レベルの規則、target tag/sa で適用先指定
Cloud Router + Cloud NATNAT Gateway2 サービスの組合せ
External IPEIP同等
Cloud RouterVPN Gateway + DX 等BGP ルータの抽象

google_compute_network

resource "google_compute_network" "main" {
  name                    = "vpc-myapp-prd"
  auto_create_subnetworks = false   # 推奨。default subnet を作らない
  routing_mode            = "REGIONAL"  # or GLOBAL

  delete_default_routes_on_create = false

  depends_on = [google_project_service.required]
}
auto_create_subnetworks の罠 デフォルト true だと、全リージョンに自動で subnet が作られ、CIDR が固定(10.x.x.x)になります。本番は必ず false

google_compute_subnetwork

resource "google_compute_subnetwork" "public" {
  name          = "snet-public-tokyo"
  network       = google_compute_network.main.id
  region        = "asia-northeast1"
  ip_cidr_range = "10.0.1.0/24"

  # Cloud Run / GKE pod 用の追加 IP 範囲(任意)
  secondary_ip_range {
    range_name    = "pods"
    ip_cidr_range = "10.10.0.0/16"
  }
  secondary_ip_range {
    range_name    = "services"
    ip_cidr_range = "10.20.0.0/20"
  }

  # VPC Flow Logs(推奨)
  log_config {
    aggregation_interval = "INTERVAL_10_MIN"
    flow_sampling        = 0.5
    metadata             = "INCLUDE_ALL_METADATA"
  }

  # Private Google Access を有効化(プライベート IP から Google API を叩く)
  private_ip_google_access = true
}

resource "google_compute_subnetwork" "private" {
  name                     = "snet-private-tokyo"
  network                  = google_compute_network.main.id
  region                   = "asia-northeast1"
  ip_cidr_range            = "10.0.11.0/24"
  private_ip_google_access = true
}

google_compute_firewall

GCP の Firewall は VPC レベル。AWS の SG と違い、「タグやサービスアカウント」で適用先 VM を指定 します。

# SSH を IAP 経由のみ許可
resource "google_compute_firewall" "ssh_iap" {
  name      = "fw-ssh-iap"
  network   = google_compute_network.main.name
  direction = "INGRESS"
  priority  = 1000

  allow {
    protocol = "tcp"
    ports    = ["22"]
  }

  source_ranges = ["35.235.240.0/20"]   # IAP 専用 IP 範囲(Google が公開)
  target_tags   = ["allow-ssh"]
}

# HTTP を Internet から許可(ロードバランサ用 VM)
resource "google_compute_firewall" "http" {
  name    = "fw-http"
  network = google_compute_network.main.name

  allow {
    protocol = "tcp"
    ports    = ["80", "443"]
  }

  source_ranges = ["0.0.0.0/0"]
  target_tags   = ["http-server"]
}

# VM 間の内部通信
resource "google_compute_firewall" "internal" {
  name    = "fw-internal"
  network = google_compute_network.main.name

  allow { protocol = "tcp"; ports = ["0-65535"] }
  allow { protocol = "udp"; ports = ["0-65535"] }
  allow { protocol = "icmp" }

  source_ranges = ["10.0.0.0/8"]   # VPC 内部
}

# デフォルト Deny(明示的)
resource "google_compute_firewall" "deny_all" {
  name      = "fw-deny-all"
  network   = google_compute_network.main.name
  direction = "INGRESS"
  priority  = 65534   # 最も低い優先度

  deny { protocol = "all" }
  source_ranges = ["0.0.0.0/0"]
}
適用先の指定 3 通りtarget_tags: VM の tags にマッチ/② target_service_accounts: VM の SA にマッチ/③ 指定なし: VPC 内全 VM。SA ベース推奨(tag は誰でも付けられるが SA はロール統制下)。

Cloud Router / Cloud NAT

プライベート VM が外部 API を叩くための仕組み。AWS NAT Gateway と違い 2 サービスの組合せ。

resource "google_compute_router" "main" {
  name    = "router-tokyo"
  region  = "asia-northeast1"
  network = google_compute_network.main.id
}

resource "google_compute_router_nat" "main" {
  name                               = "nat-tokyo"
  router                             = google_compute_router.main.name
  region                             = google_compute_router.main.region
  nat_ip_allocate_option             = "AUTO_ONLY"
  source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"

  log_config {
    enable = true
    filter = "ERRORS_ONLY"
  }
}

完成形

上の要素を組み合わせれば、AWS 章 02 と同等の パブリック/プライベート構造 の VPC が組めます。GCP では「Subnet がリージョン単位 = AZ を意識しなくていい」分、AWS よりシンプル。