examlab .net 用最有效率的方法,考取最有價值的證照
本篇導覽 約 18 分鐘

環境管理與測試

3,500 字 · 約 18 分鐘閱讀 ·

掌握 Google Cloud 上開發 (Dev)、測試 (Test)、暫存 (Staging) 和生產 (Production) 環境的架構,包括隔離策略和發佈工作流程。

立即做 20 題練習 → 免費 · 不用註冊 · PCA

環境管理簡介

有效的環境管理是專業雲端架構師 (Professional Cloud Architect) 實現卓越營運的基石。在 Google Cloud 上,必須對環境(開發 Dev、測試 Test、暫存 Staging、生產 Prod)進行架構設計,以確保隔離性、可重現性和安全性。目標是透過保持高度的環境一致性 (Environment Parity),同時控制成本並保護敏感的生產資料,來盡量減少「在我的電腦上可以執行」的問題。

白話文解釋 Environment Management

比喻 1 — 米其林星級廚房

想像開發 (Development)主廚的家庭廚房,在那裡他們嘗試新的口味。測試 (Testing)私人品酒室,在那裡他們完善菜餚。暫存 (Staging)試營運 (Soft opening),在那裡一切都與真正的餐廳完全相同,但僅限受邀嘉賓。生產 (Production) 則是週六晚上的主餐廳。你絕不會在主餐廳第一次嘗試全新的食譜!

比喻 2 — 電影劇組

開發排練室測試CGI 與混音工作室暫存是為製作人準備的私人放映會生產則是全球戲院上映。如果你在排練期間發現鏡頭中出現了收音麥克風,那沒關係;但如果它出現在戲院上映版中,那就是一場災難。

比喻 3 — 試驗工廠

在化學工程中,你不會立即建造一座巨大的工廠。你會先建造實驗室規模 (Dev),然後建造一個試驗工廠 (Pilot Plant) (Staging),看看製程是否可以按比例放大。只有當試驗工廠運作良好時,你才會建造全規模煉油廠 (Production)。

盡可能保持開發、暫存和生產環境相似的實踐,以確保程式碼在整個交付流水線中的行為保持一致。


設計環境的資源階層

在 GCP 上隔離環境最穩健的方法是在資料夾 (Folder) 結構內使用專案 (Project) 層級的隔離。

  1. 專案隔離: 每個環境都應該有自己的專案(例如:app-devapp-stagingapp-prod)。這提供了最強的安全邊界。
  2. 共享 VPC (Shared VPC): 使用共享 VPC 來集中管理網路,同時允許各個環境專案使用專屬於它們的子網路。
  3. 資料夾層級政策: 在資料夾層級(例如「開發」資料夾)套用組織政策 (Organization Policies),以執行不同的規則(例如在開發環境允許外部 IP,但在生產環境不允許)。

環境發佈工作流程

將程式碼和基礎設施從一個環境移動到下一個環境應該透過 CI/CD 自動化完成。

  • 製品發佈 (Artifact Promotion): 絕不要為不同的環境重新構建你的容器或二進位檔案。在開發/構建階段構建一次,存儲在 Artifact Registry 中,然後將同一個映像檔部署到暫存環境,接著再部署到生產環境。
  • 設定即程式碼 (Configuration as Code): 使用特定環境的設定檔或 Secret Manager,將特定環境的數值(如資料庫連線字串)注入到不可變的製品中。
::promoted

架構師洞察: 在 PCA 考試中,務必主張使用專案層級的隔離,而不是僅使用標籤或為不同環境共享專案。這可以確保開發環境中的錯誤配置(如寬鬆的防火牆規則)不會影響生產環境。 ::


管理測試資料與沙盒 (Sandboxes)

  • 資料遮罩 (Data Masking): 當使用生產資料進行測試時,務必使用 Sensitive Data Protection (DLP) 來遮罩個人識別資訊 (PII)。
  • 合成資料 (Synthetic Data): 優先考慮生成模擬生產規模和多樣性的合成資料,以避免安全風險。
  • 沙盒 (Sandboxes): 為開發人員提供具有嚴格預算警報和自動清理腳本的「遊樂場」專案,以鼓勵創新而不會導致成本失控。

Dev/Staging/Prod 專案分離模式

PCA 考試始終偏好將每個環境對應到獨立 GCP 專案、並掛在以 Organization 節點為根的資料夾結構之下。標準階層為 Organization → Environments 資料夾 → {dev、nonprod、prod} 子資料夾 → 工作負載專案。每個環境資料夾擁有自己的計費子帳戶、自己在 Cloud Identity 的緊急破窗群組,以及自己一套的 Organization Policy 綁定。

為何採用專案層級(而非標籤層級)分離

  • 配額以專案為單位。 dev 中失控的 Cloud Run 版本不會耗盡 prod 的 Compute Engine CPU 配額,前提是各自有獨立專案。
  • IAM 影響範圍縮小。 在 dev 專案授予 roles/owner,永遠不會洩漏到 prod 的 BigQuery 或 Cloud SQL 資料。
  • 記錄與稽核軌跡保持乾淨。 Cloud Audit Logs 以專案為單位彙整,因此 app-prod 的安全審查不會被開發者實驗污染。

應套用的資料夾層級護欄

政策 dev 資料夾 prod 資料夾
compute.vmExternalIpAccess 允許(子集) 拒絕
iam.allowedPolicyMemberDomains 允許外包 限公司網域
storage.uniformBucketLevelAccess 強制 強制
compute.requireOsLogin 強制 強制
sql.restrictPublicIp 允許 強制

使用 Terraform 配合 google_folder 資源與 google_org_policy_policy 綁定,讓護欄納入版本控管。再搭配 Cloud Logging 中的資料夾範圍 sink,將 prod 稽核事件路由到獨立的 BigQuery sink 以符合合規保存期(通常 7 年),而 dev 記錄可在 30 天後到期以控制成本。

若 PCA 題目提到「開發者誤刪資料庫」或「非生產 IAM 被授予到生產環境」,正確答案幾乎都是在環境資料夾下建立獨立專案,並搭配 Organization Policy 護欄 — 絕不是在共享專案內以標籤、tag 或 namespace 區隔。


以 Shared VPC 進行環境網路隔離

常見架構是每個環境一個主機專案 (host project)(例如 net-host-prodnet-host-nonprod),並將工作負載專案以服務專案 (service project) 形式掛上。這讓網路團隊集中管理網路,同時讓應用團隊保留對運算與資料服務的 IAM。

參考佈局

  • net-host-prod(主機專案)擁有 vpc-prod VPC,內含子網路 subnet-prod-asia-east1subnet-prod-us-central1
  • app-prod-* 服務專案透過僅在特定子網路上授予 roles/compute.networkUser 來消費子網路 — 切勿授予整個 VPC。
  • net-host-nonprod 託管 vpc-nonprod VPC;prod 與 nonprod 之間的 VPC Peering 故意設定,這樣 nonprod 工作負載即使誤設也無法觸及 prod 資料層。

防火牆政策階層

  1. 資料夾層級的階層式防火牆政策 (Hierarchical Firewall Policies) 拒絕來自 0.0.0.0/0 的所有流量,僅允許全域 Load Balancer 後方的 tcp:443 入向。
  2. VPC 層級的網路防火牆政策僅允許在標記服務帳戶之間的東西向流量(例如 [email protected][email protected])。
  3. 跨環境流量必須走文件化的出向路徑 — 通常透過 Cloud NAT 加上 Private Service Connect 端點,永不在 dev 與 prod 之間直接 VPC peering。

為何不採用單一 Shared VPC 涵蓋所有環境

單一 VPC 表示單一 CIDR 規劃、單一防火牆面、單一路由集合。dev 中一條誤設的路由就能使 prod 流量黑洞化。每個環境獨立 Shared VPC 多花 5 分鐘 Terraform,但移除整類跨環境事故。


各環境的 IAM 範圍限縮

身分擴散是環境洩漏的最常見來源。PCA 考試的標準答案模式:群組綁定在最低必要範圍、服務帳戶逐環境隔離、人類不持有任何常駐 prod 存取權限。

群組 + 範圍矩陣

  • gcp-app-developers@corp → 僅綁定到 dev 資料夾roles/editor
  • gcp-app-sre@corp → 綁定到 prod 資料夾roles/run.developer + roles/logging.viewer,需要 roles/run.admin 時透過 Privileged Access Manager (PAM) 走破窗流程。
  • gcp-app-deployer@corp(僅 CI/CD,無人類)→ 在每個環境綁定部署專屬角色。

服務帳戶衛生

  • 每個環境有自己的服務帳戶 namespace:[email protected][email protected] 是不同實體。
  • 在 prod 資料夾上透過 iam.disableServiceAccountKeyCreation 組織政策停用服務帳戶金鑰建立
  • CI/CD 改用 Workload Identity Federation 取代長期 JSON 金鑰 — GitHub Actions 或 GitLab CI 透過 OIDC 假冒部署 SA。
  • 跨專案 SA 假冒必須顯式:dev SA 無法假冒 prod SA,因為 roles/iam.serviceAccountTokenCreator 從未跨越環境邊界授予。

PCA 稽核清單

  • 每季執行 gcloud asset search-all-iam-policies --scope=folders/PROD_FOLDER_ID --query="policy:user:" 找出應該以群組綁定卻直接綁到個人使用者的情況。
  • 啟用 IAM Recommender 的 Policy Analyzer 找出未使用的權限,先在 dev 採納建議驗證模式,再套用到 prod。

將 prod 服務帳戶的 roles/iam.serviceAccountUser 授予 dev-developers 群組是無聲的 prod 失守 — 開發者可以用該 prod SA 啟動 Compute Engine VM 並讀取 prod 資料。永遠將 roles/iam.serviceAccountUser 限縮在 SA 被允許掛載的特定專案。


沙盒資料夾用於實驗

沙盒是防止影子 IT 的安全閥。PCA 推薦的模式是 Organization → Sandbox 資料夾,與主要 Environments 資料夾隔離,並施加嚴格護欄。

沙盒資料夾設定

  • 自動清理:Cloud Scheduler 觸發的排程 Cloud Function 執行 gcloud projects list --filter="parent.id=SANDBOX_FOLDER AND createTime<-P30D" 並刪除任何超過 30 天且未標記 keep=true 的專案。
  • 預算上限: 每個沙盒專案由 Project Factory Terraform 模組建立,自動掛上每月 50 美元的 Cloud Billing 預算,並在達 100% 時透過 Pub/Sub 觸發停用計費。
  • 不含 prod 資料: 組織政策 gcp.restrictServiceUsage 在 Sandbox 資料夾拒絕 bigquerydatatransfer.googleapis.comdatastream.googleapis.com,防止從 prod 意外建立管線。
  • 允許外部 IP,但記錄: 與 prod 不同,沙盒可有外部 IP 以利快速展示,但 VPC Flow Logs 串流到安全 SIEM,讓安全團隊可發現外洩模式。

自助流程

開發者透過 Backstage 或內部入口請求沙盒,後者呼叫 Cloud Build 觸發器。建置執行 project-factory Terraform,將請求者指派為該單一專案roles/owner(絕不在資料夾層級),並將專案 ID 貼到 Slack。這把實驗從 dev 環境(會污染共用狀態)移到短暫、有上限的空間。


Terraform Workspaces 對比 Directory-per-Environment

Terraform 提供兩種多環境 IaC 模式,PCA 考試會測試各自的適用時機。

Workspaces(CLI workspaces 或 Terraform Cloud workspaces)

# main.tf - 共用
resource "google_compute_network" "vpc" {
  name    = "vpc-${terraform.workspace}"
  project = var.project_ids[terraform.workspace]
}
  • 單一程式碼庫,每個 workspace 一份 state。
  • 優點:當環境形狀確實相同時,重複最少。
  • 缺點:容易套用到錯誤 workspace — terraform workspace select prod 拼錯一個字就是災難。

Directory-per-environment(PCA 推薦)

infra/
  modules/
    network/
    gke-cluster/
  envs/
    dev/main.tf       (以 dev 變數呼叫模組)
    staging/main.tf   (以 staging 變數呼叫模組)
    prod/main.tf      (以 prod 變數呼叫模組,獨立 backend)
  • 每個 env 有獨立 backend bucket:gs://tf-state-prodgs://tf-state-dev,並以 bucket 層級 IAM 阻止 dev pipeline SA 接觸 prod state。
  • 發佈 = 一個 PR 在 envs/staging/main.tf 提高模組版本 pin(source = "git::...//modules/gke-cluster?ref=v1.4.2"),再一個 PR 在 envs/prod/main.tf
  • 此模式與 Cloud Build 依變更路徑過濾的觸發器吻合:只有 envs/prod/ 下的變更會觸發 prod plan/apply 管線,並掛人工核准。

對混合團隊,Terraform Cloud workspaces 結合 VCS 兼具兩者優點:Git 中以目錄分環境,workspace 層級加上執行核准與稽核記錄。


各環境專屬的 Secret Manager 配置

機密絕不可跨環境共用 — 洩漏的 dev 機密不該解鎖 prod。GCP 的 Secret Manager 透過每專案機密加上機密層級 IAM 來支援這一點。

命名與專案佈局

  • 機密名稱跨環境保持穩定:db-passwordstripe-api-keyoauth-client-secret
  • 每個環境有專屬於它的專案來託管這些機密:secrets-devsecrets-stagingsecrets-prod
  • 應用讀取 projects/secrets-${ENV}/secrets/db-password/versions/latest — 唯一改變的是部署時注入的專案前綴。

各環境的存取控制

  • [email protected] 僅在 projects/secrets-prod 取得 roles/secretmanager.secretAccessor
  • roles/secretmanager.admin 永不授予人類於 prod 機密專案 — 輪替透過 Cloud Scheduler + Cloud Function 自動呼叫 Secret Manager 與上游供應商 API。
  • prod 機密啟用 CMEK 加密,金鑰位於獨立 kms-prod 專案的 Cloud KMS,因此即使具備 Secret Manager admin 但不具 roles/cloudkms.cryptoKeyDecrypter 也無法取出明文。

輪替與版本管理

  • 透過機密資源上的 rotation 欄位設定自動輪替,並觸發 Pub/Sub 主題由 Cloud Function 監聽。
  • 舊版本停用(而非銷毀)30 天以支援回滾。
  • PCA 提示:當題目描述「dev 記錄中外洩機密、需確保 prod 不受影響」,答案就是利用逐環境的專案分離 — prod 不需輪替,因為 dev 機密原本就沒有 prod 存取權。

透過 Cloud Build 替換變數 (_SECRET_PROJECT=$_ENV-secrets) 在部署時注入環境特定的機密專案 ID。應用程式碼保持環境無感、從 projects/${SECRET_PROJECT}/secrets/... 讀取 — 少一條分支要維護。


Cloud Build 替換變數驅動逐環境管線

以替換變數參數化的單一 cloudbuild.yaml 讓你可以在 dev/staging/prod 之間維護一份管線定義,由觸發器供應各環境特定值。

替換變數驅動的管線

# cloudbuild.yaml
substitutions:
  _ENV: dev
  _PROJECT_ID: app-dev
  _REGION: us-central1
  _MIN_INSTANCES: '0'
  _CMEK_KEY: ''

steps:
  - id: build
    name: gcr.io/cloud-builders/docker
    args: ['build', '-t', 'us-central1-docker.pkg.dev/$_PROJECT_ID/app/web:$SHORT_SHA', '.']

  - id: deploy
    name: gcr.io/google.com/cloudsdktool/cloud-sdk
    entrypoint: gcloud
    args:
      - run
      - deploy
      - web-$_ENV
      - --image=us-central1-docker.pkg.dev/$_PROJECT_ID/app/web:$SHORT_SHA
      - --region=$_REGION
      - --min-instances=$_MIN_INSTANCES
      - --project=$_PROJECT_ID

各環境的觸發器設定

  • dev 觸發器: 推送到 main 即觸發。替換變數:_ENV=dev, _PROJECT_ID=app-dev, _MIN_INSTANCES=0
  • staging 觸發器: 符合 staging-* 的 tag 觸發。替換變數:_ENV=staging, _PROJECT_ID=app-staging, _MIN_INSTANCES=1
  • prod 觸發器: 符合 v[0-9]+.[0-9]+.[0-9]+ 的 tag 觸發。替換變數:_ENV=prod, _PROJECT_ID=app-prod, _MIN_INSTANCES=2, _CMEK_KEY=projects/kms-prod/...需要人工核准approval_config.approval_required: true)。

每個 Cloud Build 觸發器以自己的服務帳戶執行。prod 觸發器 SA 僅在 app-prod 取得 roles/run.admin;dev 觸發器 SA 同樣僅在 app-dev 取得。絕不要跨環境共用同一個 builder SA — 那個帳戶會立刻成為整個組織內最高價值的攻擊目標。

建置時對比執行時的替換

只有 image tag、區域、資源名稱應在建置時不同。應用設定(feature flag、log level)應來自執行時來源(Secret Manager、Firestore、以 Cloud Storage 等同 App Config 的機制),使設定變更不必重新部署。從 dev 發佈到 prod 的 image SHA 必須是逐位元組相同。


GKE Config Sync 處理各環境政策

對於跨環境執行 GKE 的組織,Config Sync(Anthos Config Management 的一部分)以 GitOps 提供各叢集的政策與設定交付。

儲存庫結構

config-sync/
  base/                    (共用 Kustomize base — namespace、network policy)
  overlays/
    dev/
      patches/
        deny-internet.yaml   (限制較鬆)
        resource-quotas.yaml (較小配額)
    staging/
    prod/
      patches/
        deny-internet.yaml   (拒絕所有出向,僅允許 allowlist)
        resource-quotas.yaml (生產規模)
        pod-security.yaml    (restricted PSS)

每個 GKE 叢集(gke-devgke-staginggke-prod)有自己的 RootSync 資源,指向同一 Git repo 中不同的 overlay 路徑,確保所有叢集追蹤單一事實來源,同時套用各環境合適的限制。

各環境的 Policy Controller (Gatekeeper)

Policy Controller 透過 OPA Gatekeeper 範本強制限制:

  • dev: 大多限制為 warn 模式,讓開發者看到違規但不阻擋部署。
  • staging: 關鍵限制為 deny 模式(禁止 privileged container、hostNetwork),對 image registry 限制則為 warn-only。
  • prod: 所有限制為 deny 模式,包括 K8sAllowedRepos 將映像限制在 *-docker.pkg.dev/PROD_PROJECT/*

偏移偵測與修復

Config Sync 持續對 Git 調節叢集狀態。若開發者透過 kubectl edit 手動編輯 prod 的 NetworkPolicy,Config Sync 會在數秒內回復,並向 Cloud Monitoring 發出觸發 PagerDuty 警報的指標。這使 prod 在 Git 工作流之外實質上不可變 — 與你希望 IaC 層提供的特性相同,只是套用到 Kubernetes API 層。


透過 Cloud Run 提供短暫的預覽環境

每個 PR 一個預覽環境能大幅改善開發者回饋迴圈。Cloud Run 是 GCP 上的首選服務,因為它有亞秒級冷啟動、可縮容到零的計費,以及每個版本一個 URL。

實作模式

  1. pull_request 觸發的 GitHub Actions workflow 建置容器,標記 pr-${PR_NUMBER}-${SHA} 並推送到 Artifact Registry
  2. Workflow 執行 gcloud run deploy preview-pr-${PR_NUMBER} --image=... --region=us-central1 --no-traffic,為每個 PR 建立新的 Cloud Run 服務。
  3. Cloud Run 回傳確定的 URL https://preview-pr-123-xyz-uc.a.run.app,workflow 將其貼為 PR 留言。
  4. PR 關閉(合併或放棄)時,後續 workflow 執行 gcloud run services delete preview-pr-${PR_NUMBER}

成本與安全護欄

  • 所有預覽服務位於專屬 app-preview 專案(非 dev、非 staging)。
  • --min-instances=0--max-instances=3 將閒置成本維持為零、活躍成本設上限。
  • 預覽 SA 對獨立 BigQuery 資料集中已淨化的 staging 資料副本具備唯讀存取 — 永不及於生產。
  • 啟用 Cloud Run 認證--no-allow-unauthenticated),開發者透過 gcloud auth print-identity-token 或綁定公司網域的 Identity-Aware Proxy 認證。

為何不採用 GKE 預覽

每個 PR 一個 GKE namespace 雖可行,但增加排程延遲(拉映像、排程 Pod)與 namespace 清理成本。Cloud Run 30 秒內提供全新 URL、開發者互動之間可縮容到零,並省去叢集資源管理。GKE 預覽應保留給 Cloud Run 無法承載、具黏滯狀態(資料庫、StatefulSet)的工作負載。


暫存環境的資料匿名化

暫存必須真實鏡像生產,又不能成為合規負債。Sensitive Data Protection (DLP)DataflowCloud KMS 的組合提供可重複的匿名化管線。

管線架構

  1. 排程 BigQuery 匯出透過 BigQuery Data Transfer Service 以僅具 prod 唯讀的 SA 每晚把 prod 資料表快照到綁定 staging 的 Cloud Storage bucket。
  2. Dataflow 範本(Google 提供的 Cloud_DLP_GCS_Text_to_BigQuery 範本)讀取快照、以 DeidentifyConfig 呼叫 DLP API,再寫入 staging BigQuery 資料集。
  3. DLP 設定使用:
    • 對電子郵件與電話欄位使用 FFX 的格式保留加密 (FPE),使參考完整性得以保留(相同 prod 電子郵件永遠對應到相同 staging 電子郵件)。
    • 對 SSN/國民身分證欄位使用密碼學雜湊,金鑰位於獨立 kms-deid 專案的 Cloud KMS
    • 對薪資等數值欄位使用桶化 (Bucketing)< 5000050000-100000> 100000)以保留統計特性而不暴露精確值。
    • 對時間戳記使用日期位移並以每筆記錄一致的位移量,讓時間序列分析仍可運作。

再識別控制

  • FPE 使用的 KMS 金鑰包覆在僅去識別化 SA 可使用的 KMS key ring 之下。再識別需顯式 IAM 授予,並觸發 Cloud Audit Log 警報。
  • Staging 存取由獨立群組 gcp-app-staging-readers@corp 把關,預設不授予產品工程師 — 即使資料已匿名化,最小權限原則仍適用。

發佈前驗證

Staging 資料上線前,Cloud Run job 執行 k-匿名性與 l-多樣性檢查(使用 DLP 的 RiskAnalysisJob),確認匿名化資料集達到組織的隱私門檻(例如 k≥5)。若工作失敗,staging 重整中止並觸發警報 — 防止意外弱化的匿名化進入工程師視線。

PCA 測試資料情境的標準答案:DLP + Dataflow 是 GCP 原生的大規模匿名化方案,搭配需要參考完整性的欄位使用格式保留加密、單向假名化使用密碼學雜湊、統計欄位使用桶化/日期位移。把去識別化的 KMS 金鑰放在獨立專案以強制職責分離。


常見問題 — 環境管理

Q1. 我們如何確保開發環境和生產環境之間的一致性?

使用基礎設施即程式碼 (Terraform)。定義一次基礎設施並使用變數將其部署到多個專案。這可以確保網路、防火牆和服務配置完全相同。

Q2. 開發環境和生產環境應該在同一個 VPC 中嗎?

不應該。為了獲得高度安全性,請將它們放在分開的 VPC 中(可能是在共享 VPC 架構中,它們佔用不同的子網路並由防火牆規則隔離)。

Q3. 我們如何控制開發/測試環境的成本?

使用 Cloud Scheduler 在非工作時間關閉非生產用 VM,使用 Preemptible/Spot VM,並設置積極的 Cloud Billing 預算

Q4. 暫存環境 (Staging) 的作用是什麼?

暫存環境是用於最終驗證。它應該是生產環境的 1:1 複製品,包括資料量(已遮罩)和流量模式,以便發現效能問題和整合錯誤。

Q5. 我們可以在不同環境中使用相同的 Service Accounts 嗎?

絕對不行。每個環境都必須擁有自己唯一的 Service Accounts,其權限範圍僅限於該環境的資源。

官方資料來源

更多 PCA 主題