Skip to content

Verification, Hooks & Cloud Deploy Automation

Tại sao cần Hooks và Verification

Rolling update hay canary đơn giản nhất chỉ deploy manifests lên cluster và kiểm tra Deployment rollout status. Trong production thực tế, đây thường không đủ:

  • Database migrations: Phải chạy migration script trước khi deploy new code (pre-deploy hook)
  • Cache warming: Warm up cache sau khi deploy để tránh cold-start latency spike (post-deploy hook)
  • Smoke tests: Verify endpoints respond đúng sau khi deploy (verify job)
  • Integration tests: Đảm bảo downstream services không bị ảnh hưởng
  • Rollback triggers: Tự động rollback nếu error rate tăng sau deploy

Cloud Deploy giải quyết những nhu cầu này qua ba mechanisms: hooks (pre/post-deploy), verify jobs, và automation (trigger actions dựa trên rollout events).


Pre-Deploy và Post-Deploy Hooks

Cơ chế hoạt động

Hooks là arbitrary programs được cấu hình để chạy như jobs trong Rollout lifecycle. Theo tài liệu Cloud Deploy:

"The predeploy hook always runs as the first job in the phase. The postdeploy hook always runs as the last job — unless verification is configured, in which case verification runs before the postdeploy job."

Execution order trong một phase:

predeploy hook → deploy job → verify job → postdeploy hook

Cấu hình hooks trong clouddeploy.yaml:

yaml
serialPipeline:
  stages:
  - targetId: prod-gke
    profiles: [production]
    predeploy:
      actions: [migrate-db, warm-cache-preflight]
    postdeploy:
      actions: [notify-slack, run-smoke-tests]

Actions reference customActions được định nghĩa trong skaffold.yaml:

yaml
# skaffold.yaml
customActions:
- name: migrate-db
  containers:
  - name: db-migrator
    image: us-central1-docker.pkg.dev/my-project/repo/db-migrator
    command: ["/bin/migrate"]
    args: ["--direction=up", "--env=production"]
- name: warm-cache-preflight
  containers:
  - name: cache-warmer
    image: us-central1-docker.pkg.dev/my-project/repo/cache-warmer
    command: ["/bin/warm.sh"]
    args: ["--preflight-only"]

Idempotency — Yêu cầu bắt buộc

Cloud Deploy explicitly yêu cầu hooks là idempotent:

"Deploy hooks are assumed to be idempotent. If a given action is run more than once, there is no additional effect."

Lý do: nếu một job bị interrupted và retry, nó sẽ chạy lại từ đầu. Database migration phải idempotent: nếu migration đã chạy, chạy lại không gây double-apply. Pattern phổ biến: check-then-act, hoặc dùng migration framework (Flyway, Liquibase) với versioning.

Execution Environment của Hooks

Theo mặc định, hooks chạy trong Cloud Deploy execution environment (Cloud Build workers). Tuy nhiên, với GKE targets, có thể cấu hình hook chạy trực tiếp trên cluster:

yaml
# skaffold.yaml
customActions:
- name: run-integration-tests
  executionMode:
    kubernetesCluster: {}   # Chạy trên cluster, không phải Cloud Build worker
  containers:
  - name: test-runner
    image: my-test-runner
    command: ["pytest", "/tests/integration/"]

Với kubernetesCluster: {}, Cloud Deploy tạo một Kubernetes Job trên target cluster để chạy hook container. Điều này cho phép hook:

  • Access internal cluster services (internal DNS)
  • Dùng existing service mesh configuration
  • Không cần network connectivity từ Cloud Build đến internal services

Giới hạn: Cloud Run targets không hỗ trợ kubernetesCluster execution mode — chỉ cloud build execution environment.

Environment Variables trong Hooks

Cloud Deploy inject context variables vào hook containers:

CLOUD_DEPLOY_DELIVERY_PIPELINE=my-app-pipeline
CLOUD_DEPLOY_RELEASE=release-v1-2-3
CLOUD_DEPLOY_ROLLOUT=rollout-prod-001
CLOUD_DEPLOY_TARGET=prod-gke
CLOUD_DEPLOY_LOCATION=us-central1
CLOUD_DEPLOY_PROJECT=my-project
CLOUD_DEPLOY_JOB_RUN=jobrun-abc123
GKE_CLUSTER=projects/my-project/locations/us-central1/clusters/prod-cluster

Hook scripts có thể dùng variables này để logging có context hoặc gọi Cloud Deploy API để report status.


Verify Jobs — Post-Deploy Validation

Verify job là một loại job đặc biệt chạy sau deploy phase để validate deployment health. Trong canary deployments, verify job quyết định có advance sang phase tiếp theo hay không.

yaml
# clouddeploy.yaml — enable verify cho canary phase
strategy:
  canary:
    canaryDeployment:
      percentages: [10, 50]
      verify: true

# skaffold.yaml — define verify jobs
verify:
- name: check-latency
  container:
    name: latency-checker
    image: my-verifier:latest
    command: ["/bin/check-latency.sh"]
    args:
    - "--threshold-p99=200ms"
    - "--window=2m"
    - "--metric=custom.googleapis.com/app/latency"
- name: check-error-rate
  container:
    name: error-checker
    image: my-verifier:latest
    command: ["/bin/check-errors.sh"]
    args: ["--threshold=0.001"]  # 0.1% error rate threshold

Multiple verify jobs chạy serially — nếu một job fail, các jobs sau không chạy.

Verify Job trên GKE — Kubernetes Job

Tương tự hooks, verify jobs trên GKE có thể chạy như Kubernetes Job:

yaml
# skaffold.yaml
verify:
- name: integration-test-suite
  executionMode:
    kubernetesCluster: {}
  container:
    name: test-runner
    image: my-integration-tests
    command: ["go", "test", "./tests/integration/...", "-v"]
    env:
    - name: TEST_ENDPOINT
      value: "http://my-app-svc.default.svc.cluster.local"

Chạy integration tests trực tiếp trong cluster cho phép test against internal service endpoints — không cần expose services ra public internet chỉ để test.


Cloud Deploy Automation

Automation là tính năng cho phép Cloud Deploy tự động thực hiện actions dựa trên rollout events — không cần manual trigger.

Automation Types

1. Release Promotion Automation

Tự động promote release sang stage tiếp theo sau khi rollout thành công:

yaml
apiVersion: deploy.cloud.google.com/v1
kind: Automation
metadata:
  name: auto-promote-to-staging
  region: us-central1
description: "Auto-promote từ dev sang staging sau khi dev rollout thành công"
suspended: false
serviceAccount: deploy-sa@my-project.iam.gserviceaccount.com
selector:
  targets:
  - id: dev-gke    # Trigger khi rollout trên target này thành công
rules:
- name: promote-rule
  promoteReleaseRule:
    id: promote-staging
    wait: 15m      # Chờ 15 phút sau khi dev succeed trước khi promote
    toTargetId: "@next"  # "@next" = stage tiếp theo trong pipeline

@next là alias đặc biệt: luôn refer đến stage tiếp theo sau source target trong pipeline definition. Điều này cho phép automation config không cần hardcode target names.

2. Scheduled Release Promotion

Promote theo cron schedule thay vì event trigger:

yaml
rules:
- name: scheduled-prod-promote
  promoteReleaseRule:
    id: promote-prod
    wait: 0s
    toTargetId: prod-gke
    schedule: "0 2 * * 1-5"   # 2:00 AM weekdays (UTC)

Use case: deploy staging tự động vào ban đêm sau khi dev team hoàn thành sprint. Promote lên production vào giờ thấp điểm theo schedule.

3. Canary Phase Advance Automation

Tự động advance canary phase sau khi verify thành công:

yaml
rules:
- name: auto-advance-canary
  advanceRolloutRule:
    id: advance-canary
    wait: 30m    # Chờ 30 phút ở mỗi canary phase trước khi advance
    sourcePhase: "canary-10"

Cần một rule per phase muốn tự động advance. Thường kết hợp với verify jobs: nếu verify pass và wait time đủ, advance tự động.

4. Rollback Repair Automation

Tự động rollback khi rollout fail:

yaml
rules:
- name: auto-rollback-on-failure
  repairRolloutRule:
    id: rollback-failed-deploy
    jobs:
    - deploy
    - verify
    repairPhases:
    - rollback:
        destinationPhase: stable   # Rollback về state trước canary

Đây là automation quan trọng nhất cho production safety: nếu verify fail hoặc deploy fail, không cần engineer on-call can thiệp ngay — hệ thống tự rollback.

AutomationRun — Execution Record

Mỗi khi automation trigger, Cloud Deploy tạo một AutomationRun resource — immutable record của automation execution:

AutomationRun auto-promote-to-staging-run-abc123
├── status: SUCCEEDED
├── automationId: auto-promote-to-staging
├── ruleId: promote-staging
├── sourceTarget: dev-gke
├── triggerRollout: rollout-dev-001
├── promotedRelease: release-v1-2-3
└── targetTarget: staging-gke

AutomationRun cho phép:

  • Audit trail của mọi automated action
  • Debug tại sao automation không trigger (check rule conditions)
  • Cancel automation đang pending

Automation và Manual Gates

Điểm quan trọng: automation không bypass manual approval gates. Nếu Target có requireApproval: true, automation có thể trigger promotion nhưng Rollout vẫn dừng ở PENDING_APPROVAL cho đến khi approver approve.

Đây là thiết kế đúng: automation handle routine work (promote dev→staging), nhưng human gate vẫn kiểm soát production.

Suspended Automation

Có thể suspend automation tạm thời mà không xóa:

bash
gcloud deploy automations update auto-promote-to-staging \
  --delivery-pipeline=my-app-pipeline \
  --region=us-central1 \
  --suspended

Use case: trong incident, muốn pause automatic promotions để team có thời gian điều tra. Sau khi giải quyết xong, unsuspend để automation tiếp tục.

Theo tài liệu Cloud Deploy: "Suspended automations continue generating platform logs for debugging." Quan trọng: automation bị suspend vẫn log các events sẽ-trigger nhưng không trigger — giúp audit "automation sẽ làm gì nếu không bị suspend".


Failure Handling — Retry và Rollback

Job Retry

Khi một Job fail trong Rollout:

yaml
rules:
- name: retry-deploy-on-failure
  repairRolloutRule:
    id: retry-deploy
    jobs:
    - deploy
    repairPhases:
    - retry:
        attempts: 3
        backoffMode: LINEAR    # LINEAR hoặc EXPONENTIAL
        wait: 5m

Retry automation sẽ re-execute failed job tối đa N lần. Phù hợp cho transient failures (network timeout, temporary resource unavailability).

Rollback Automation

Sau khi exhaust retry attempts, rollback automation kick in:

yaml
repairPhases:
- retry:
    attempts: 2
    wait: 5m
- rollback:
    destinationPhase: stable   # Rollback về phase stable (pre-canary state)

Đây là pattern phổ biến: thử 2 lần, nếu vẫn fail thì tự động rollback.


Anti-patterns

Anti-pattern 1: Hooks không idempotent

bash
# SAI — chạy lại sẽ apply migration 2 lần
psql -c "ALTER TABLE users ADD COLUMN new_field VARCHAR(255);"

# ĐÚNG — idempotent check
psql -c "ALTER TABLE users ADD COLUMN IF NOT EXISTS new_field VARCHAR(255);"

Anti-pattern 2: Verify job timeout quá ngắn

Verify job cần đủ thời gian để collect meaningful metrics. P99 latency metric cần traffic đủ để sample. Set verify job timeout dựa trên actual traffic volume:

  • Low-traffic service: cần 5-10 phút để đủ data points
  • High-traffic service: 2-3 phút có thể đủ

Anti-pattern 3: Automation promote liên tục không có verify

yaml
# NGUY HIỂM — promote dev → staging → prod trong vòng vài phút
- promoteReleaseRule:
    wait: 0s
    toTargetId: "@next"

Automation không có wait time hay verify = mọi bad deploy từ dev tự động lên production trong vài phút. Cần minimum wait time và verify jobs, đặc biệt với production promote automation.


Official References