返回列表

GCP帳號購買 GCP 伺服器自動化維運:使用 Terraform 快速建置與擴展 VM

谷歌雲GCP / 2026-07-25 17:35:17

前言:把伺服器維運從手工變成可複製的流程

多數團隊在 GCP 建 VM 的第一步是手動點選,接著用腳本安裝程式、開防火牆、調整磁碟與監控。當服務變多、環境擴張,手工做法會迅速失控:設定漂移、版本不一致、跨環境差異、回滾困難。把這些步驟收斂在 Terraform 中,以宣告式、可審查、可回溯的方式管理,能把維運變成可複製的工程能力,讓建置、擴展與異動都可預期且安全。

本文從設計原則出發,示範最小可用範本(Minimum Viable VM)、模組化、CI/CD、彈性擴展(MIG + Autoscaler)、監控告警與成本控管,最後給出上線前檢核清單,讓你能直接落地。

為什麼用 Terraform 管理 GCP VM

Terraform 能把基礎設施描述成程式碼:檔案可版本化、審查、重用,並透過 Plan 先看差異、再 Apply 套用變更。這套流程把風險移到開發階段,降低線上操作的不確定性,並讓團隊可藉由代碼審查建立一致與安全的規範。

在 GCP,VM 維運往往牽涉網路(VPC、子網、路由)、身份與權限(IAM、Service Account)、資料磁碟、開機映像、健康檢查與監控。把這些都寫進 Terraform,可同時解決跨環境一致性與自動化部署兩大難題。

設計原則與整體架構

落地 Terraform 的關鍵不是工具本身,而是設計方式。以下原則能讓代碼可長期維護:

分層與目錄結構

把「環境」與「功能」分層。範例結構:

infra/
  modules/
    network/
    vm/
    mig/
  envs/
    dev/
      main.tf
      terraform.tfvars
    prod/
      main.tf
      terraform.tfvars

modules 由可重用的模組組成;envs 代表具體的部署場景(dev、staging、prod),只做參數化,避免在環境層寫太多邏輯。

變數、輸出與約束

為模組設計清楚的介面:必要變數加上型別與驗證、合理的預設值、輸出(outputs)回傳重要資訊(如 IP、SelfLink、Service Account)。在介面上做約束,比在使用時補救來得可靠。

狀態檔與鎖定

Terraform 狀態檔是事實來源。使用 GCS 作為遠端 state 並開啟鎖定,避免多人同時 Apply 導致競態。搭配版本控管與 PR 审核,形成「代碼審查 + 計畫差異 + 鎖定」的三重保護。

不可變基礎設施

盡量追求不可變:更新改用新的 Instance Template 或映像,讓 VM 用滾動更新替換,減少在機器上「手改」。這是降低漂移與不可解錯誤的核心策略。

GCP帳號購買 最小可用 VM 範本

先建立最小可用 VM:具備網路、基本防火牆、服務帳戶、啟動指令,並把狀態存到 GCS。以下示範單個環境 main.tf 筆記式範本:

terraform {
  required_version = ">= 1.5.0"
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 5.0"
    }
  }
  backend "gcs" {
    bucket = "tf-state-prod"
    prefix = "vm/base"
  }
}

provider "google" {
  project = var.project_id
  region  = var.region
  zone    = var.zone
}

variable "project_id" {
  type = string
}
variable "region" {
  type    = string
  default = "asia-east1"
}
variable "zone" {
  type    = string
  default = "asia-east1-a"
}

resource "google_compute_network" "vpc" {
  name                    = "app-vpc"
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "subnet" {
  name          = "app-subnet"
  network       = google_compute_network.vpc.id
  ip_cidr_range = "10.10.0.0/24"
  region        = var.region
}

resource "google_service_account" "vm_sa" {
  account_id   = "vm-runtime-sa"
  display_name = "VM Runtime SA"
}

resource "google_compute_firewall" "allow_ssh_http" {
  name    = "allow-ssh-http"
  network = google_compute_network.vpc.name

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

  source_ranges = ["0.0.0.0/0"]
}

resource "google_compute_instance" "vm" {
  name         = "app-vm-01"
  machine_type = "e2-medium"
  zone         = var.zone

  boot_disk {
    initialize_params {
      image = "projects/debian-cloud/global/images/family/debian-12"
      size  = 20
      type  = "pd-balanced"
    }
  }

  network_interface {
    subnetwork = google_compute_subnetwork.subnet.id
    access_config {}
  }

  service_account {
    email  = google_service_account.vm_sa.email
    scopes = ["https://www.googleapis.com/auth/cloud-platform"]
  }

  metadata_startup_script = <<EOT
#!/bin/bash
set -euo pipefail
apt-get update -y
apt-get install -y nginx
systemctl enable nginx
systemctl start nginx
EOT
}

output "vm_external_ip" {
  value = google_compute_instance.vm.network_interface[0].access_config[0].nat_ip
}

這份最小範本確保 VM 可運作、有基本網路與權限、能啟動服務。下一步是把它抽象成模組,讓多環境重用且易於擴展。

GCP帳號購買 模組化擴展:可重用 VM 模組

把 VM 抽成 modules/vm,暴露必要參數與輸出,並避免把環境特定的值寫死在模組裡。模組的目標:清楚、穩定、可測試、可長期維護。

模組介面設計

module "web_vm" {
  source       = "../modules/vm"
  name         = "web"
  machine_type = "e2-standard-2"
  image_family = "debian-12"
  disk_size_gb = 20
  network_id   = google_compute_network.vpc.id
  subnetwork   = google_compute_subnetwork.subnet.id
  service_account_email = google_service_account.vm_sa.email
  startup_script         = file("./scripts/install_web.sh")
  tags = ["web", "http"]
}

在模組內,提供合理預設與型別檢查;同時輸出如外部 IP、內部 IP、SelfLink 供其他資源引用。避免在模組內進行環境判斷(如 if env==prod),改由環境層提供變數差異。

環境差異的處理

dev 可用較小機型與開放更寬鬆的防火牆;prod 使用固定映像、較嚴格 IAM、二次確認的 Plan。把差異留在 envs/dev、envs/prod 的 tfvars,搭配同一個模組,讓一致的結構承載不同的策略。

自動化部署:把 Terraform 納入 CI/CD

把 Terraform 流程從本機移到 CI/CD,讓每次變更都留痕、可審查、可回滾。基本步驟:

Pipeline 範例

steps:
  - run: terraform fmt -check
  - run: terraform init -backend-config=bucket=tf-state-prod -backend-config=prefix=vm/base
  - run: terraform validate
  - run: terraform plan -out=tfplan
  - run: terraform show -no-color tfplan > plan.txt
  - hold: Manual approval for prod
  - run: terraform apply tfplan

關鍵點:Plan/Apply 分離;prod 要有人為核准;將 plan 輸出存檔,便於審查與追溯。把敏感參數(如密鑰、密碼)從 CI 的秘密管理注入,避免寫死在代碼或 tfvars 中。

變更審核與漂移檢測

把 plan.txt 當成審核檔,若出現 destroy 或大規模 replace,必須二次確認。定期跑 terraform plan(只讀),抓出漂移:手工改防火牆或機型可能導致狀態不一致,提早發現就能避免線上故障。

彈性擴展:Managed Instance Group 與 Autoscaler

單台 VM 只是開始;要應付流量高峰與更新,就該轉成 Managed Instance Group(MIG)與自動擴縮。作法是用 Instance Template 定義 VM,MIG 管理多副本,Autoscaler 根據指標擴容。

核心資源範例

resource "google_compute_instance_template" "web_tpl" {
  name_prefix  = "web-tpl-"
  machine_type = "e2-standard-2"

  disk {
    source_image = "projects/debian-cloud/global/images/family/debian-12"
    auto_delete  = true
    boot         = true
    disk_type    = "pd-balanced"
    disk_size_gb = 20
  }

  network_interface {
    subnetwork = google_compute_subnetwork.subnet.id
    access_config {}
  }

  service_account {
    email  = google_service_account.vm_sa.email
    scopes = ["https://www.googleapis.com/auth/cloud-platform"]
  }

  metadata_startup_script = file("./scripts/install_web.sh")
  tags = ["web", "http"]
}

resource "google_compute_health_check" "web_hc" {
  name = "web-hc"
  http_health_check {
    port = 80
    request_path = "/"
  }
}

resource "google_compute_region_instance_group_manager" "web_mig" {
  name               = "web-mig"
  base_instance_name = "web"
  region             = var.region
  version {
    instance_template = google_compute_instance_template.web_tpl.self_link
  }
  target_size = 2
  auto_healing_policies {
    health_check      = google_compute_health_check.web_hc.id
    initial_delay_sec = 60
  }
}

resource "google_compute_region_autoscaler" "web_as" {
  name   = "web-as"
  region = var.region
  target = google_compute_region_instance_group_manager.web_mig.id
  autoscaling_policy {
    min_replicas = 2
    max_replicas = 10
    cpu_utilization {
      target = 0.6
    }
    cooldown_period = 60
  }
}

這組資源讓你的服務可自動擴縮。更新時改用新的 Instance Template,MIG 滾動替換,不必手改線上機器。健康檢查確保只把健康節點納入負載。

無中斷部署策略

把版本引入 Instance Template 名稱或標籤,用 MIG 的 version 區塊做滾動更新。設定合理的最大不可用數量(max surge / max unavailable)與健康檢查延遲,讓更新過程對使用者透明。

網路、身份與映像:把風險前移

網路與 IAM 是最常見的風險源。建議策略:

IAM 最小權限

為 VM 創建專用 Service Account,賦予最小角色(如讀取 Storage、Pub/Sub Publisher 等)。把對整專案的 Owner 角色移除,改以工作流程授權。CI 執行 Terraform 的身分也應使用最小權限、並限制範圍。

秘密管理與映像硬化

敏感資訊用秘密管理服務保存與注入;在映像層做硬化:關閉不必要的服務、更新套件、設定檔案權限與 SSH 原則。最好以映像管線(Packer 或建置映像流程)產出可版本化的基礎映像,再由 Terraform 參照。

監控、日誌與告警:讓擴展有憑有據

GCP帳號購買 把監控與告警也寫進 Terraform:建立指標、告警策略與通知管道。至少監控 CPU、記憶體、磁碟 I/O、HTTP 成功率與延遲;告警門檻應分層:預警(可觀察)與致命(需介入)。

指標選擇與門檻區分

Autoscaler 常用 CPU 平均作為指標,但對 I/O 重的服務應改用負載或自訂指標。門檻設計要考慮冷啟成本與波動,避免抖動。搭配降噪策略(抑制、聚合),讓告警可行動而非吵雜。

成本控管:把擴展與預算綁在一起

擴展如果沒有預算約束,很容易超支。做法:為不同環境或服務設置配額與上限;選擇合適機型(e2、c3、t2a 等)與磁碟(pd-balanced、pd-ssd);善用承諾使用折扣與自動關機策略(非峰時段)。在 Terraform 中暴露上限(max_replicas),並以 Policy 驗證變更不會突破預算。

GCP帳號購買 常見陷阱與排障心法

幾個在 GCP + Terraform 維運上經常遇到的問題與處理心得:

狀態檔競態

多人同時 Apply 導致資源互相覆蓋。解法:遠端 state + 鎖定、在 CI 統一入口、禁止直接在本機對 prod Apply。

不一致的手工設定

有人在 Console 上改防火牆或 IAM,導致 plan 有大量漂移。解法:把所有資源都落進 Terraform,並定期跑只讀 plan 做漂移掃描。

啟動腳本失敗

metadata_startup_script 是常見故障點。解法:腳本前置 set -euo pipefail;把安裝日誌輸出到 /var/log;以映像管線把依賴前移,減少啟動時安裝。

滾動更新中斷

健康檢查門檻過嚴或延遲過短,導致新節點未準備好就被標示不健康。解法:調整 initial_delay、health check path 與超時,並檢查服務啟動時間。

Autoscaler 抖動

指標噪音造成頻繁擴縮,帶來成本與不穩定。解法:提高冷卻時間、採移動平均或以自訂指標控制,並限制最小增長單位。

演進路線圖:從單 VM 到自動化集群

實務上的演進步驟可分三段:

階段一:固定版位、最小可用

建立最小可用 VM 範本與模組;使用遠端 state;把網路與防火牆納入代碼;導入基本 CI(fmt、validate、plan)。

階段二:可擴展與可觀察

導入 MIG + Autoscaler;健康檢查、滾動更新;監控與告警策略;把敏感資訊改用秘密管理;開始做 Policy 驗證與成本門檻。

階段三:規模化與治理

把所有環境與專案統一規範;模組版本管理與發佈;PR 驗證與變更審核制度;自動漂移檢測與修復;持續優化映像與安全基線。

實用範本與檢核清單

最後給一份上線前檢核清單,確保基礎設施到位、可觀察、可回滾:

上線前檢核清單

  • 代碼:所有資源均納入 Terraform;模組介面清楚,變數型別與驗證完整。
  • 狀態:使用 GCS 遠端 state,鎖定有效;plan.txt 存檔並審查。
  • 網路:VPC、子網、路由、DNS 與防火牆規則一致;無手工例外。
  • 身份:VM 有專用 Service Account;CI 身分最小權限;角色與範圍明確。
  • 映像:啟動腳本可重入、具日誌;基礎映像經硬化與版本化。
  • MIG:健康檢查通過;滾動更新策略測試;Autoscaler 門檻合理且不抖動。
  • 監控:CPU、延遲、錯誤率、磁碟 I/O 指標已建立;告警分層且通知管道有效。
  • 成本:機型選型合理;設定最大副本數與配額;有預算監控與警示。
  • 安全:敏感資訊不進代碼;SSH 政策與防火牆最小曝光;審計日誌保留。
  • GCP帳號購買 流程:CI/CD 有手動核准門檻;回滾程序清楚;變更紀錄與標籤完善。

結語:把複雜事用簡單方法重複做好

把 GCP VM 的建置與維運寫成 Terraform,不只是在追趕自動化潮流,而是用工程方法處理複雜性:讓每次部署可預期、每次修改可審查、每次擴展有依據。先從最小可用開始,逐步模組化與導入 MIG + Autoscaler,再把監控、成本與安全納入治理。當流程與代碼成熟,你的基礎設施會像產品一樣進化,而不是一次性的配置。

團隊文化也會隨之改變:用 PR 討論變更、用指標衡量穩定、用回滾保證安全。最終,你會擁有一套可複製、可伸縮、可審查的維運系統,支撐快速交付與長期成長。

Telegram售前客服
客服ID
@cloudcup
联系
Telegram售后客服
客服ID
@yanhuacloud
联系