Skip to content
JCJohnny Chung
← All posts

Khi AI Viết Infrastructure Code: Tại Sao Team Mình Bắt Buộc Phải Thay Đổi Cách Review Và Deploy

Phân tích thực chiến về rủi ro khi ship code AI-generated lên production K8s/Edge, cách xây dựng guardrails observability và quy trình review mới để kiểm soát tech debt ngầm.

· 7 min read

kỹ sư review code trên màn hình

Ảnh: Matthew Henry, CC0 qua openverse (nguồn)

Sáng thứ Ba tuần trước, on-call nhận alert: latency p99 của service payment gateway nhảy từ 120ms lên 2.3s. Không có deploy mới, không có config change, không có traffic spike. Chỉ có một PR merged đêm hôm trước — viết bởi Cursor, approved bằng LGTM nhanh vì “code trông clean, test pass”.

Root cause mất 47 phút: một retry loop vô hạn trong circuit breaker config mà AI hallucinate. Parameter maxRetries: -1 thay vì maxRetries: 3. Unit test mock happy path nên không bắt được. Integration test không chạy vì CI pipeline skip stage e2e để “tiết kiệm thời gian”.

Vấn đề không phải ở AI. Vấn đề ở chỗ team mình — và hầu hết team khác — đang dùng quy trình review, test, deploy của năm 2020 cho code được sinh ra năm 2026.

Bối cảnh: AI viết code nhanh hơn team review gấp 10 lần

HN thread “Ask HN: How to deal with shipping AI-written code you don’t understand?” đang nóng 300+ comment. Meta engineer chia sẻ: “I’m writing code these days and it all feels like a black box. This new standard of shipping with AI is moving so fast that if we’re going to spend our time checking each line of code, it’s…”

Thực tế tại dự án trước: team 8 dev, 3 tháng qua 73% LOC mới từ Copilot/Cursor/Claude Code. Velocity tăng 40% theo metric Jira. Nhưng incident severity-1 tăng 3x. Rollback rate từ 2% lên 12%. Tech debt không còn là “code cũ” mà là “code AI sinh ra hôm qua mà không ai hiểu”.

Điểm mấu chốt: AI không viết bug. AI viết code plausible — trông đúng, compile pass, test pass, nhưng logic sai ở chỗ không có spec rõ ràng. Infrastructure code (Terraform, Helm, K8s manifests, Cloudflare Workers script) nguy hiểm hơn app code vì blast radius lớn hơn.

Phân tích sâu: Hai lớp rủi ro infrastructure đặc thù

Lớp 1: Configuration drift ngầm

AI sinh Helm values.yaml, Terraform module, K8s NetworkPolicy dựa trên pattern training data. Nhưng production environment có nuance mà training data không bao gồm:

  • Node pool taint/toleration mismatch khiến pod schedule sai zone
  • Cloudflare Workers KV namespace binding case-sensitive mà AI viết camelCase
  • Istio sidecar injection label missing trên namespace mới
  • Resource limit/request ratio vi phạm VPA recommendation

cấu hình Kubernetes cluster

Ảnh: Jemimus, BY qua openverse (nguồn)

Lần đầu gặp: AI generate PodDisruptionBudget với minAvailable: 50% cho deployment 3 replicas. Kết quả: rolling update bị block vì 50% của 3 = 1.5 → round up = 2. Cluster không thể drain node cho maintenance. AI không hiểu semantics của Kubernetes scheduler.

Lớp 2: Observability gap

Code AI-generated thường thiếu:

  • Structured logging với correlation ID
  • Custom metrics cho business logic quan trọng
  • Distributed tracing propagation qua async boundary
  • Health check endpoint phản ánh dependency thực tế

Khi incident xảy ra, on-call nhìn dashboard thấy “service healthy” nhưng user báo lỗi. Vì health check chỉ check http.Get("/healthz") return 200, không check DB connection, Redis latency, downstream API contract.

Giải pháp: Guardrails thay vì Gatekeeping

Không thể review từng dòng. Cần hệ thống tự động bắt lỗi trước khi vào production. Team mình triển khai 3 lớp guardrails:

1. Static analysis cho infrastructure-as-code

# .github/workflows/iac-guardrails.yml
jobs:
  tfsec:
    runs-on: ubuntu-latest
    steps:
      - uses: aquasecurity/tfsec-action@v1.0.3
        with:
          soft_fail: false
  kubeconform:
    runs-on: ubuntu-latest
    steps:
      - uses: yannh/kubeconform-action@v1
        with:
          strict: true
          kubernetes_version: "1.29.0"
  helm-unittest:
    runs-on: ubuntu-latest
    steps:
      - uses: helm/unittest-action@v1
        with:
          chart_dir: ./charts

Bổ sung custom rules:

  • Cấm hostNetwork: true trừ khi có annotation security-review: approved
  • Yêu cầu resources.limits.memory ≤ 2x resources.requests.memory
  • Bắt buộc podAntiAffinity cho workload production
  • Kiểm tra imagePullPolicy: Always cho tag latest

2. Contract testing cho AI-generated API client

AI hay sinh HTTP client với retry policy, timeout, circuit breaker mặc định. Viết contract test dùng Pact hoặc schemathesis:

# tests/contract/test_payment_gateway.py
import schemathesis
from hypothesis import given

schema = schemathesis.openapi.from_path("../openapi/payment-gateway.yaml")

@schema.parametrize()
@given(data=st.data())
def test_ai_generated_client_conforms_to_contract(case, data):
    # Case được generate từ OpenAPI spec, không phải từ code AI
    response = case.call_wsgi_app(wsgi_app)
    case.validate_response(response)
    
    # Kiểm tra thêm: retry-after header, idempotency key handling
    if response.status_code == 429:
        assert "Retry-After" in response.headers

Contract test chạy trong CI trước integration test. Nếu AI sinh client vi phạm spec (missing header, wrong retry logic), fail ngay.

3. Canary deployment với synthetic traffic

Không deploy straight to production. Dùng Argo Rollouts + synthetic traffic generator:

# rollout.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: payment-gateway
spec:
  replicas: 10
  strategy:
    canary:
      canaryMetadata:
        labels:
          role: canary
      steps:
        - setWeight: 5
        - pause: {duration: 5m}
        - analysis:
            templates:
              - templateName: success-rate-analysis
        - setWeight: 25
        - pause: {duration: 10m}
        - analysis:
            templates:
              - templateName: latency-analysis
        - setWeight: 50
        - pause: {duration: 15m}
        - setWeight: 100

Analysis template query Prometheus:

# analysis-template.yaml
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate-analysis
spec:
  metrics:
    - name: success-rate
      interval: 1m
      count: 5
      successCondition: result[0] >= 0.999
      failureLimit: 1
      provider:
        prometheus:
          address: http://prometheus.monitoring.svc:9090
          query: |
            sum(rate(http_requests_total{job="payment-gateway",code=~"2.."}[1m]))
            /
            sum(rate(http_requests_total{job="payment-gateway"}[1m]))

Synthetic traffic generator (k6 script) chạy liên tục against canary:

// k6/synthetic-payment.js
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  stages: [
    { duration: '2m', target: 50 },  // ramp up
    { duration: '5m', target: 50 },  // steady
    { duration: '2m', target: 0 },   // ramp down
  ],
  thresholds: {
    'http_req_duration{p99}': ['p(99)<500'],
    'http_req_failed': ['rate<0.001'],
  },
};

const payload = JSON.stringify({
  amount: 10000,
  currency: 'VND',
  idempotency_key: `test-${__VU}-${__ITER}`,
});

export default function () {
  const res = http.post('https://canary.payment-gateway.internal/v1/charges', payload, {
    headers: { 'Content-Type': 'application/json', 'X-Request-Source': 'synthetic' },
  });
  check(res, {
    'status 200': (r) => r.status === 200,
    'response has charge_id': (r) => r.json('charge_id') !== undefined,
  });
  sleep(1);
}

Kết quả: 3 incident severity-1 bị bắt ở canary stage trong 2 tháng qua. Zero rollback production từ AI-generated code.

Quy trình review mới: “Trust but verify” thay vì “Read every line”

Code review checklist cho AI-generated PR

Team mình dùng template PR description bắt buộc:

## AI-Generated Code Checklist
- [ ] Tool used: Cursor / Copilot / Claude Code / Other: ____
- [ ] Prompt context attached (screenshot or link)
- [ ] Business logic verified by human: ____ (reviewer name)
- [ ] Edge cases covered in unit test: ____
- [ ] Integration test path: ____
- [ ] Observability added: logs / metrics / traces / none
- [ ] Rollback plan: ____
- [ ] Security review needed: yes / no

Reviewer chỉ focus 3 điểm:

  1. Business logic correctness — AI có hiểu requirement không?
  2. Observability completeness — có thể debug khi production burn không?
  3. Blast radius — nếu code này sai, ảnh hưởng bao nhiêu service?

Không review: coding style, variable naming, design pattern (trừ khi vi phạm project convention).

Pair programming với AI sebagai navigator

Thay vì dev viết code → AI review, đảo ngược: AI viết draft → dev verify logic → AI refactor → dev approve. Quy trình này giảm 60% thời gian review theo metric team.

# Script tự động gán reviewer dựa trên file pattern
# .github/auto-reviewer.yml
# Team infrastructure review Terraform, Helm, K8s manifests
# Team platform review Cloudflare Workers, Edge config
# Team security review RBAC, NetworkPolicy, Secret handling

Kết luận actionable

Tóm lại: AI-generated infrastructure code không phải vấn đề — quy trình cũ mới là vấn đề. Ba hành động cụ thể:

  1. Tuần này: Bật tfsec, kubeconform, helm-unittest trong CI. Fail build nếu violation. Không exception.
  2. Tháng này: Viết contract test cho 5 critical path API. Setup Argo Rollouts + synthetic traffic cho 3 service quan trọng nhất.
  3. Quý này: Đào tạo team pair-program với AI. Đo lường: review time, escape defect rate, rollback rate. Adjust guardrails theo data.

bảng điều khiển observability

Ảnh: U.S. Forest Service (source), CC0 qua openverse (nguồn)

Và quan trọng nhất: đừng để “code trông clean, test pass” trở thành tiêu chuẩn accept. Tiêu chuẩn là: “on-call có thể debug lúc 3 sáng không cần gọi tác giả”. Nếu AI sinh code mà team không hiểu — đừng merge. Viết lại, hoặc đợi spec rõ ràng hơn.

Tech debt từ AI-generated code không phải nợ tài chính — là nợ an toàn. Và nợ an toàn không có grace period.


Bạn đang xử lý AI-generated code như thế nào trong pipeline? Share kinh nghiệm ở comment — team mình đang collect pattern để cải thiện guardrails layer 4: automated remediation.