はじめに
AWS と Terraformをメインに仕事をしていた私が、Google Cloudでの構築案件に入ることになりました。
Google Cloudそのものは多少触ったことがあるものの、IaC(Terraform)でゼロから構築するのはほぼ初めて。
今回はGoogle Cloud Run・Google Cloud NAT・Google Cloud Pub/Subを含む構成をTerraformで構築した経験をもとに、
AWSの経験をベースに、Google CloudをTerraformで構築する際に押さえておきたいポイントを紹介します。
これまでTerraformを書いてきて、これからGoogle Cloudに取り組む方の参考になれば幸いです。
今回の構成概要
外部クライアント
↓
Google Cloud Run(サーバーレスコンテナ)
↓(VPC経由のアウトバウンド通信)
Google Cloud NAT → インターネット / 外部サービス
+ Google Cloud Pub/Sub(モニタリング連携用)
+ Google Cloud Secret Manager(認証情報の管理)
+ VPC Flow Logs(ネットワーク監査)構築環境はWSL + VS Code + Claude Code + Terraform v1.13.0です。
最初に押さえておきたい5つの構築ポイント
① サービスを使う前にAPIを有効化する必要がある
Google Cloudは「権限カードを持っていても、使う部屋ごとに受付で鍵を開けてもらう必要があるビル」のイメージGoogle Cloudでは、IAMの権限に加えて、サービスごとにAPIを有効化する必要があります。
これを忘れると「APIが有効化されていません」というエラーで詰まります。
Terraformでは google_project_service で宣言的に管理できます。
resource "google_project_service" "run" {
service = "run.googleapis.com"
disable_on_destroy = false
}
resource "google_project_service" "secretmanager" {
service = "secretmanager.googleapis.com"
disable_on_destroy = false
}今回使ったサービスで有効化が必要だったもの:
| サービス | API名 |
|---|---|
| Google Cloud Run | run.googleapis.com |
| Google Cloud Secret Manager | secretmanager.googleapis.com |
| Google Cloud Pub/Sub | pubsub.googleapis.com |
| Google Cloud NAT | compute.googleapis.com |
| VPC Flow Logs | logging.googleapis.com |
disable_on_destroy = false にしておくのがポイントです。
true(デフォルト)のままだと terraform destroy 時にAPIが無効化され、
他のリソースが依存していた場合に影響が出ます。
② Google CloudのVPC仕様(グローバルスコープ)のポイント
日本全体に1棟のビルを建てて、大阪フロア・東京フロアに分けるイメージGoogle CloudのVPCはグローバルスコープです。
VPC自体はリージョンをまたいで1つで運用でき、サブネットはリージョン単位で作成します。
# Google CloudのVPCはリージョンを指定しない
resource "google_compute_network" "main" {
name = "main-vpc"
auto_create_subnetworks = false
}
# サブネットはリージョンを指定する
resource "google_compute_subnetwork" "main" {
name = "main-subnet"
region = "asia-northeast1"
network = google_compute_network.main.id
ip_cidr_range = "10.0.0.0/24"
log_config {
aggregation_interval = "INTERVAL_5_SEC"
flow_sampling = 0.5
metadata = "INCLUDE_ALL_METADATA"
}
}Google CloudのVPC/サブネット基本仕様
| 項目 | 仕様 |
|---|---|
| VPCのスコープ | グローバル(リージョンをまたいで1つで運用できる) |
| サブネットのスコープ | リージョン |
| VPC Flow Logsの有効化単位 | サブネット(log_configで設定) |
| デフォルトVPC | あり(auto mode)。今回は auto_create_subnetworks = false でサブネットを自分で定義 |
③ Service AccountとIAMバインディングの構成
「社員証を発行する → 入館権限を登録する → 人に持たせる」の3ステップのイメージGoogle Cloudでリソースに権限を持たせるときは、次の3ステップで構成します。
- Service Accountを作成する
- IAMバインディングで、Service Accountに権限を付与する
- Service Accountをリソース(今回はGoogle Cloud Run)に割り当てる
# 1. Service Accountを作る
resource "google_service_account" "cloud_run_sa" {
account_id = "cloud-run-sa"
display_name = "Cloud Run Service Account"
}
# 2. Service AccountにGoogle Cloud Secret Managerへのアクセス権を付与
resource "google_secret_manager_secret_iam_member" "secret_access" {
secret_id = google_secret_manager_secret.my_secret.secret_id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${google_service_account.cloud_run_sa.email}"
}
# 3. Google Cloud RunにService Accountを割り当てる
resource "google_cloud_run_v2_service" "main" {
name = "my-service"
location = "asia-northeast1"
template {
service_account = google_service_account.cloud_run_sa.email
}
}※AWSのIAMロールのアタッチに近いイメージです。
構造を理解すると読みやすいですが、最初は「どのリソースにどのIAMバインディングが必要か」の把握に時間がかかりました。
リソースを追加するたびに、3ステップのどれが必要かを確認すると整理しやすくなります。
④ Google Cloud RunはデフォルトでVPCに接続されていない
Google Cloud Runは「デフォルトではオフィスの外で働く外部スタッフ」のイメージ
社内ネットワーク(VPC)に入るには明示的な手続きが必要。Google Cloud Runは、デフォルトではVPCに接続されていません。
VPC内のリソースへのアクセスや、Google Cloud NATを経由したアウトバウンド通信には明示的な設定が必要です。
resource "google_cloud_run_v2_service" "main" {
name = "my-service"
location = "asia-northeast1"
template {
vpc_access {
network_interfaces {
network = google_compute_network.main.id
subnetwork = google_compute_subnetwork.main.id
}
# PRIVATE_RANGES_ONLY: VPC内通信のみVPC経由
# ALL_TRAFFIC: 全アウトバウンドをVPC経由(Google Cloud NAT適用)
egress = "ALL_TRAFFIC"
}
}
}egress = "ALL_TRAFFIC" にすることで、Google Cloud RunからのアウトバウンドがGoogle Cloud NATを経由します。
外部サービスへの通信をNAT経由で行いたい場合はこの設定が必要です。
Google Cloud NATのTerraformはこちら:
resource "google_compute_router" "main" {
name = "main-router"
region = "asia-northeast1"
network = google_compute_network.main.id
}
resource "google_compute_router_nat" "main" {
name = "main-nat"
router = google_compute_router.main.name
region = "asia-northeast1"
nat_ip_allocate_option = "AUTO_ONLY"
source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"
}⑤ Google Cloud Runのコールドスタートに注意
「普段誰も来ない部屋の電気は消えている」状態で、最初の来客時だけ「電気を点けるまでの時間」が発生するイメージ。
min_instance_count = 1 は常に電気を点けっぱなしにする設定で、その分コストがかかる。Google Cloud Runはリクエストがないときはインスタンスがゼロになります。
久しぶりのリクエストでコールドスタートが発生し、応答が遅くなることがあります。
同期的な処理(呼び出し側がレスポンスを待つアーキテクチャ)では特に影響が出やすいです。
Terraformで最小インスタンス数を設定して対応できます。
resource "google_cloud_run_v2_service" "main" {
template {
scaling {
min_instance_count = 1 # 常時1インスタンス起動(コールドスタート回避)
max_instance_count = 10
}
}
}ただし min_instance_count = 1 にすると常時課金が発生します。
アクセス頻度と応答速度要件を考慮した上で設定しましょう。
まとめ
Google CloudをTerraformで構築する際に、最初に押さえておきたいポイントをまとめます。
| # | ポイント | Terraformでの設定・対応 |
|---|---|---|
| ① | サービスごとにAPIの有効化が必要 | google_project_serviceで宣言的に管理 |
| ② | VPCはグローバルスコープ | サブネットにリージョンを指定 |
| ③ | 権限はService AccountとIAMバインディングで構成 | SA作成 → 権限付与 → Google Cloud Runへ割当の3ステップ |
| ④ | Google Cloud RunはデフォルトでVPC外 | vpc_accessとegressを明示的に設定 |
| ⑤ | コールドスタートが発生する | min_instance_countで調整 |
Terraformの書き方の基本は、これまでの経験がそのまま活かせます。
Google Cloud特有の仕様を最初に把握しておくと、詰まりどころが減ります。
特に「API有効化」と「Google Cloud RunとVPCの関係」は最初に押さえておくと良いと思います。
参考
- Google Cloud 公式ドキュメント「Cloud Run」 https://cloud.google.com/run/docs
- Terraform Google Provider ドキュメント https://registry.terraform.io/providers/hashicorp/google/latest/docs
- Google Cloud 公式ドキュメント「Cloud NAT」 https://cloud.google.com/nat/docs