1. Google Provider 配置与认证
一句话总结: google Provider 通过 project 与凭证链完成初始化,生产推荐用服务账户(SA)的 JSON 密钥或 Workload Identity,避免在代码中硬编码密钥。
Google Cloud 以 Project 为资源边界。动手前先把 Project ID、区域(region)与可用区(zone)固定下来,Provider 用 google 与 google-beta 两个版本覆盖 GA 与预览 API。
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
google-beta = {
source = "hashicorp/google-beta"
version = "~> 5.0"
}
}
}
provider "google" {
project = var.project_id
region = var.region
zone = var.zone
}
1.1 凭证方式的取舍
| 方式 | 配置途径 | 适用场景 |
|---|---|---|
| 环境变量 | GOOGLE_APPLICATION_CREDENTIALS 指向 JSON | CI 注入、本地开发 |
| gcloud 登录 | gcloud auth application-default login | 单机日常开发 |
| 服务账户 | credentials 字段或 SA 密钥文件 | 团队统一身份 |
| Workload Identity | 运行在 GKE 上的负载自动获取 | 云端 Runner、Pod 内运行 |
生产环境最推荐 服务账户 + Workload Identity 的组合:代码里不出现任何长期密钥,权限由 IAM 统一治理。
export GOOGLE_APPLICATION_CREDENTIALS="$HOME/.config/gcp/platform-sa.json"
gcloud config set project my-project
terraform plan
一句话:Provider 是「配置模板」,Project 是「资源归属」,凭证决定「谁在操作」,三者先行定好再谈资源。
2. 服务账户与权限
一句话总结: 服务账户是 GCP 的身份实体,用 google_service_account 声明、google_project_iam_member 赋权,遵循「一角色一职责」的最小权限原则。
GCP 权限体系以服务账户(Service Account)与 IAM 角色为核心。先建 SA,再按资源作用域绑定角色。
resource "google_service_account" "app" {
account_id = "app-runner"
display_name = "应用运行服务账户"
}
resource "google_project_iam_member" "app_logging" {
project = var.project_id
role = "roles/logging.logWriter"
member = "serviceAccount:${google_service_account.app.email}"
}
resource "google_storage_bucket_iam_member" "app_assets" {
bucket = google_storage_bucket.assets.name
role = "roles/storage.objectViewer"
member = "serviceAccount:${google_service_account.app.email}"
}
一句话:SA 是身份,IAM 绑定是权限,作用域限定到 Project、Bucket、Topic 等具体资源,权限泛滥的根子就在「给了过大的角色」。
3. VPC 网络与负载均衡
一句话总结: GCP 的 VPC 是全局网络,子网按区域划分,防火墙规则按标签放行,负载均衡由转发规则 + 后端服务组合,跨区域可用 Global LB。
GCP VPC 的一个特点是「全局网络 + 区域子网」:VPC 覆盖整个 Project,子网才绑定区域。防火墙规则用网络标签(network tag)精确控制目标实例。
resource "google_compute_network" "main" {
name = "vpc-${var.environment}"
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "web" {
name = "subnet-web-${var.region}"
network = google_compute_network.main.id
region = var.region
ip_cidr_range = "10.10.1.0/24"
}
resource "google_compute_firewall" "allow_web" {
name = "fw-allow-web"
network = google_compute_network.main.name
allow {
protocol = "tcp"
ports = ["80", "443"]
}
source_ranges = ["0.0.0.0/0"]
target_tags = ["web"]
}
3.1 全球负载均衡
对外服务用 google_compute_global_forwarding_rule + google_compute_backend_service,把多区域实例组聚合成一个公网入口。
resource "google_compute_backend_service" "web" {
name = "backend-web"
port_name = "http"
protocol = "HTTP"
load_balancing_scheme = "EXTERNAL"
backend {
group = google_compute_instance_group.web.id
}
health_checks = [google_compute_health_check.web.id]
}
resource "google_compute_health_check" "web" {
name = "hc-web"
check_interval_sec = 10
http_health_check {
port = 80
path = "/healthz"
}
}
resource "google_compute_global_forwarding_rule" "web" {
name = "fw-global-web"
target = google_compute_target_http_proxy.web.id
port_range = "80"
}
一句话:GCP 网络以「全局 VPC + 区域子网 + 防火墙标签」组织,负载均衡把后端实例组抽象成一个稳定入口,跨区域容灾交给 Global LB。
4. GCE 计算实例
一句话总结: GCE 用 google_compute_instance 声明,启动脚本走 metadata 的 startup-script,实例模板 + 实例组是横向伸缩的标准姿势。
单台 VM 用 google_compute_instance,生产建议用实例模板(instance template)+ 托管实例组(MIG)承接自动伸缩与滚动更新。
resource "google_compute_instance" "web" {
name = "web-${var.environment}"
machine_type = "e2-small"
zone = var.zone
boot_disk {
initialize_params {
image = "ubuntu-os-cloud/ubuntu-2204-lts"
size = 20
}
}
network_interface {
network = google_compute_network.main.name
subnetwork = google_compute_subnetwork.web.name
access_config {} # 分配临时公网 IP
}
metadata_startup_script = <<-EOT
#!/bin/bash
apt-get update -y
apt-get install -y nginx
systemctl enable nginx
EOT
service_account {
email = google_service_account.app.email
scopes = ["cloud-platform"]
}
tags = ["web"]
}
4.1 实例模板与托管实例组
把启动逻辑与磁盘配置写进模板,MIG 按 min/max 自动扩缩,健康检查失败自动重建。
resource "google_compute_instance_template" "web" {
name = "tmpl-web"
machine_type = "e2-small"
disk {
source_image = "ubuntu-os-cloud/ubuntu-2204-lts"
auto_delete = true
}
network_interface {
network = google_compute_network.main.name
}
metadata_startup_script = "systemctl start nginx"
}
resource "google_compute_region_instance_group_manager" "web" {
name = "mig-web"
base_instance_name = "web"
region = var.region
target_size = 3
version {
instance_template = google_compute_instance_template.web.id
}
named_port {
name = "http"
port = 80
}
}
一句话:模板定义「长什么样」,MIG 定义「多少个、怎么伸缩」,滚动更新只需换模板版本。
5. GKE 集群编排
一句话总结: GKE 用 google_container_cluster 声明控制面与默认节点池,业务负载放独立 NodePool,身份走 Workload Identity,kubeconfig 用 gcloud 安全获取。
GKE 是 GCP 的托管 Kubernetes。集群声明在 google_container_cluster,额外节点池用 google_container_node_pool。
resource "google_container_cluster" "gke" {
name = "gke-${var.environment}"
location = var.region
remove_default_node_pool = true
initial_node_count = 1
network = google_compute_network.main.name
subnetwork = google_compute_subnetwork.web.name
workload_identity_config {
workload_pool = "${var.project_id}.svc.id.goog"
}
}
resource "google_container_node_pool" "primary" {
name = "primary"
location = var.region
cluster = google_container_cluster.gke.name
node_count = 3
node_config {
machine_type = "e2-standard-2"
oauth_scopes = [
"https://www.googleapis.com/auth/cloud-platform",
]
}
}
5.1 Workload Identity
把 GKE 上的 Pod 身份映射到服务账户,避免把 SA 密钥烧进镜像。
resource "google_project_iam_member" "gke_app" {
project = var.project_id
role = "roles/cloudsql.client"
member = "serviceAccount:${var.project_id}.svc.id.goog[default/app]"
}
一句话:GKE 托管控制面、自管节点池,Workload Identity 让 Pod 以服务账户身份访问 GCP API,是容器上云的安全基线。
6. CloudSQL 数据库
一句话总结: CloudSQL 用 google_sql_database_instance 声明,私有 IP 走 VPC、只对应用网段开放授权,开启备份、高可用与维护窗口。
数据库实例建议用私有 IP 接入 VPC,应用从内网访问;公网访问通过 authorized_networks 限定来源。
resource "google_sql_database_instance" "postgres" {
name = "pg-${var.environment}"
database_version = "POSTGRES_15"
region = var.region
settings {
tier = "db-f1-micro"
disk_size = 50
disk_type = "PD_SSD"
availability_type = "ZONAL"
backup_configuration {
enabled = true
start_time = "02:00"
point_in_time_recovery_enabled = true
}
ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.main.id
}
}
}
resource "google_sql_database" "appdb" {
name = "appdb"
instance = google_sql_database_instance.postgres.name
}
一句话:CloudSQL 的核心是「私有网络 + 备份 + 高可用」三件套,密码永远走密钥系统而非 IaC 仓库。
7. 成本优化与标签治理
一句话总结: GCP 成本治理靠「统一标签 + committed use discount + 自动停止」三件套,标签让账单可归属,折扣降单价,调度省空闲。
成本优化的第一步是让每笔费用可归属。用 labels 标记环境、成本中心,再用预算告警盯住异常。
resource "google_billing_budget" "monthly" {
billing_account = var.billing_account
display_name = "月度预算-${var.environment}"
budget_filter {
projects = ["projects/${var.project_id}"]
labels = {
environment = var.environment
}
}
amount {
specified_amount {
currency_code = "CNY"
units = 10000
}
}
threshold_rules {
threshold_percent = 0.8
}
}
7.1 标签与调度
所有资源统一补 environment 与 cost_center 标签,开发机用 google_compute_resource_policy 定时停止。
resource "google_compute_resource_policy" "nightly_stop" {
name = "nightly-stop-dev"
region = var.region
instance_schedule_policy {
time_zone = "Asia/Shanghai"
schedule = "0 22 * * *"
vm_start_schedule {
schedule = "0 9 * * 1-5"
}
vm_stop_schedule {
schedule = "0 22 * * *"
}
}
}
一句话:GCP 的账单按标签聚合,打标是成本归属的前提;长期运行的服务用 Committed Use Discount,开发环境用调度停止。
8. 总结
一套真实可用的 GCP 基础设施,核心是把 Project、身份、网络、计算、容器、数据库、成本七类资源按「引用组合」的方式组织起来:
| 环节 | 要点 |
|---|---|
| Provider | project/region/zone + 凭证链 + google/google-beta |
| 身份 | SA + IAM 绑定,作用域限定到具体资源 |
| 网络 | 全局 VPC + 区域子网 + 防火墙标签 + Global LB |
| 计算 | 实例模板 + MIG 自动伸缩 |
| 容器 | GKE + 独立 NodePool + Workload Identity |
| 数据库 | CloudSQL 私有 IP + 备份 + 高可用 |
| 成本 | 标签 + 预算告警 + 调度停止固化成代码 |
一句话收尾:GCP 实战与 AWS 的最大差异在「全局 VPC」与「Project 级隔离」。把 Project 规划、SA 最小权限、标签成本治理这三件事做对,这套模板就能在 dev/staging/prod 之间稳定复制。下一篇「AWS 网络进阶」将深入 AWS 特有的 VPC 互联与多账户网络隔离。
延伸阅读
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。