★ 初級

02. Project と階層

GCP のすべてのリソースは 必ず Project に属します。Project は AWS Account に相当しますが、もっと軽量で 用途別に何個でも作る のが推奨スタイル。

GCP リソース階層

[Organization]            ← 組織(Workspace ドメインに紐づく)
   ├── [Folder]           ← 任意の中間階層(部門・環境ごと)
   │     ├── [Project A]
   │     └── [Project B]
   └── [Folder]
         ├── [Project C]
         │     ├── google_compute_network
         │     ├── google_storage_bucket
         │     └── google_compute_instance
         └── [Project D]

Folder は省略可。最小構成は Organization → Project → Resource。

AWS との対応

GCPAWSAzure
OrganizationOrganizations RootTenant
FolderOrganizational Unit (OU)Management Group
ProjectAccountSubscription
ResourceResourceResource (within RG)

大きな違い: GCP の Project は AWS Account より遥かに軽量。コマンド一発で作れる。プロジェクトを「使い捨てる」運用が普通。

Project を Terraform で作る

resource "google_project" "app" {
  name            = "myapp-prd"
  project_id      = "myapp-prd-${random_id.suffix.hex}"   # 全世界一意
  org_id          = "123456789012"
  billing_account = "ABCDEF-123456-789012"

  labels = {
    env     = "prd"
    owner   = "platform-team"
    managed = "terraform"
  }

  # デフォルトのネットワークは無効化(推奨)
  auto_create_network = false
}

resource "random_id" "suffix" {
  byte_length = 4
}
project_id の制約 project_id は全 GCP で一意。6-30 文字、英小文字・数字・ハイフンのみ、先頭は英字、末尾はハイフン不可。一度決めると変更不可。

API の有効化(service enable)

GCP は 「使う API を明示的に有効化」 が必須。AWS と違って初期状態では何も使えない。Terraform から制御します。

resource "google_project_service" "required" {
  for_each = toset([
    "compute.googleapis.com",          # Compute Engine, VPC
    "storage.googleapis.com",          # Cloud Storage
    "iam.googleapis.com",
    "cloudresourcemanager.googleapis.com",
    "secretmanager.googleapis.com",
    "cloudkms.googleapis.com",
    "run.googleapis.com",              # Cloud Run
    "logging.googleapis.com",
    "monitoring.googleapis.com",
    "sql-component.googleapis.com",
    "sqladmin.googleapis.com",         # Cloud SQL
    "artifactregistry.googleapis.com", # Artifact Registry
    "dns.googleapis.com",
  ])

  project = google_project.app.project_id
  service = each.value

  disable_on_destroy         = false   # destroy 時に API を無効化しない(重要)
  disable_dependent_services = false
}
disable_on_destroy の罠 デフォルト true だと terraform destroy 時に API を無効化します。他リソースで使っているとカスケード障害。本番では 必ず false

Project 分割戦略

パターン適性
環境ごとmyapp-dev / myapp-stg / myapp-prd◎ 最も一般的
環境×サービスmyapp-prd-api / myapp-prd-data○ 大規模で有効
共有 vs 個別shared-network + 各 app project○ Shared VPC パターン
すべて 1 つeverything-prd△ 学習用のみ

GCP の特徴は 「Project を消せば中身も全部消える」。Terraform で簡単に作って捨てられるので、PR ごとに ephemeral project を作るような運用も可能。

Labels(GCP 版タグ)

GCP では「タグ」ではなく「Labels」と呼びます。仕様にちょっとクセが:

locals {
  common_labels = {
    project    = "myapp"
    env        = "prd"
    owner      = "platform-team"
    managed_by = "terraform"
  }
}

resource "google_storage_bucket" "data" {
  name     = "myapp-prd-data"
  location = "ASIA-NORTHEAST1"
  labels   = local.common_labels
}

provider レベルの default_labels (Terraform google v5+)

provider "google" {
  project = "myapp-prd"
  region  = "asia-northeast1"

  default_labels = {
    project    = "myapp"
    env        = "prd"
    managed_by = "terraform"
  }
}
# このプロバイダで作る全リソースに自動付与