169 lines
11 KiB
Markdown
169 lines
11 KiB
Markdown
# ADR-016 — Chiến lược triển khai Blue-Green qua AWS CodeDeploy cho 3 dịch vụ ECS
|
||
|
||
*Tên file: `adr/ADR-016_blue-green-deploy-aws-codedeploy.md`*
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Status** | `Proposed` |
|
||
| **Date** | 2026-09-15 |
|
||
| **Người quyết** | SA + Ops/SRE (hạ tầng/HA/DR/chi phí vận hành — `decision-radar.md §5`; PO phủ quyết nếu vượt ngân sách) — chưa ký thật |
|
||
| **Người đề xuất** | SA (qua skill `sa-2-architecture`, hoạt động `adr`) |
|
||
| **Điểm radar** | **6/10** *(chấm theo `decision-radar.md §2`, kế thừa nguyên ước lượng đã ghi ở `INF_e-commerce_v1.0.md §7.2`: Chi phí đảo ngược=1 (đổi chiến lược deploy sau khi đã cấu hình CodeDeploy cho 3 service tốn vài tuần, không phải migrate dữ liệu) · Bán kính ảnh hưởng=2 (toàn bộ 3 đơn vị triển khai — Nhóm Giao dịch, Nhóm Hỗ trợ, Payment) · Chạm `QAS` Must=2 (trực tiếp `QAS-007`, ngân sách lỗi 43 phút/tháng) · Ràng buộc dài hạn=1 (ràng buộc trong phạm vi chiến lược release hiện tại, đổi được qua `ADR` mới) · Tranh cãi=0 → **6 ⇒ `ADR` bắt buộc**, dưới ngưỡng 8, không bắt buộc POC)* |
|
||
| **Supersedes** | — |
|
||
| **Superseded by** | — |
|
||
| **Liên quan** | `QAS-007` · `ASR-011` · `OQ-020` · `OQ-056` · `ADR-010` · `ADR-012` · `INF_e-commerce_v1.0.md §6.4, §7` · `DEC-30` |
|
||
|
||
> ⚠️ **ADR bất biến sau khi `Accepted`.** Muốn đổi quyết định thì viết ADR mới có
|
||
> `Supersedes: ADR-016` và đổi trạng thái bản cũ thành `Superseded by`. Không sửa nội dung ADR
|
||
> đã `Accepted`, không xoá ADR đã `Rejected`.
|
||
|
||
---
|
||
|
||
## 0. Ghi chú Preflight & ngoại lệ gate
|
||
|
||
Viết cùng lượt với `ADR-014`/`ADR-015`/`ADR-017` dưới ngoại lệ gate ghi ở `DEC-31` (tiếp nối
|
||
`DEC-01…30`) — xem `ADR-014 §0` cho bối cảnh đầy đủ. Riêng `ADR-016`: hiện thực hoá đề xuất đã ghi
|
||
ở `INF_e-commerce_v1.0.md §7.2` (duyệt từng phần, `DEC-30`).
|
||
|
||
---
|
||
|
||
## 1. Bối cảnh
|
||
|
||
`QAS-007` (error budget) đặt ngân sách lỗi **43 phút/tháng** cho Catalog/Checkout/Payment/Identity
|
||
(99,9%/tháng), loại trừ bảo trì có báo trước ≤2 giờ/tháng (`OQ-020`, TẠM — chưa PO xác nhận số
|
||
cuối). `INF §6.4` ghi rõ ràng buộc: chiến lược deploy **không được tự tiêu tốn ngân sách lỗi này**
|
||
— chọn sai chiến lược release (VD rolling update có cửa sổ mất traffic ngắn mỗi lần) tích luỹ
|
||
qua nhiều lần release/tháng có thể ăn hết 43 phút mà không liên quan gì tới sự cố thật.
|
||
|
||
`ADR-012` đã chốt 3 đơn vị triển khai độc lập: Nhóm Giao dịch, Nhóm Hỗ trợ, Payment (ECS Fargate).
|
||
Mỗi service cần một chiến lược release nhất quán, không phải mỗi module một kiểu.
|
||
|
||
**Ràng buộc đang chi phối:**
|
||
|
||
| Nguồn | Nội dung |
|
||
|---|---|
|
||
| `QAS-007` | Ngân sách lỗi 43 phút/tháng, loại trừ bảo trì ≤2h/tháng (`OQ-020`, TẠM) |
|
||
| `ASR-011` | Observability & alerting — cần phát hiện lỗi sau deploy nhanh để rollback kịp thời |
|
||
| `CON-08` | Năng lực đội vận hành chưa xác nhận đầy đủ — chọn chiến lược không quá phức tạp để đội vận hành được |
|
||
|
||
**Cái đã biết chắc / cái còn là giả định:**
|
||
|
||
| Điều | 🟢 Đã kiểm chứng / 🔴 Giả định | Bằng chứng |
|
||
|---|---|---|
|
||
| AWS CodeDeploy hỗ trợ blue-green cho ECS như một tính năng managed sẵn có | 🟢 Đã kiểm chứng — theo tài liệu AWS công khai | `INF §7.2` |
|
||
| Đội chưa từng vận hành CodeDeploy blue-green trong production | 🔴 Giả định — chưa xác nhận | `CON-05`/`CON-08`, `OQ-008` |
|
||
| Rollback bằng chuyển traffic ALB (green→blue) là tức thời (giây), không cần redeploy | 🟢 Đã kiểm chứng — tính năng CodeDeploy | `INF §7.2` |
|
||
|
||
## 2. Phương án đã cân nhắc
|
||
|
||
### PA-1 — Rolling update
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Mô tả** | Thay thế dần từng task cũ bằng task mới, giữ một phần traffic route tới task đang tắt trong thời gian ngắn |
|
||
| **Ưu** | Đơn giản, là chế độ mặc định của ECS, không cần cấu hình CodeDeploy thêm |
|
||
| **Nhược** | Có cửa sổ ngắn (vài giây) mỗi lần deploy mà request có thể chạm task đang tắt (draining) — tích luỹ nhiều lần release/tháng có nguy cơ ăn vào ngân sách lỗi 43 phút/tháng (`QAS-007`); rollback chậm hơn (phải redeploy version cũ, không phải chuyển traffic tức thời) |
|
||
| **Chi phí đảo ngược** | Thấp — đổi sang blue-green sau vẫn khả thi, không tốn nhiều |
|
||
|
||
### PA-2 — Blue-green qua AWS CodeDeploy *(chọn)*
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Mô tả** | Deploy phiên bản mới sang một target group "green" song song với "blue" đang chạy; sau khi health check pass, chuyển toàn bộ traffic ALB sang "green" dứt điểm; giữ "blue" một thời gian để rollback tức thời nếu phát hiện lỗi |
|
||
| **Ưu** | Tương thích ngân sách lỗi chặt (`QAS-007`) — 0 downtime theo thiết kế nếu health check đúng; rollback tức thời (chuyển traffic lại, không cần redeploy) |
|
||
| **Nhược** | Cần double capacity tạm thời trong cửa sổ chuyển đổi (cả blue lẫn green cùng chạy) — tăng chi phí nhỏ trong thời gian ngắn; đội cần học vận hành CodeDeploy (chưa có kinh nghiệm, `CON-05`/`CON-08`) |
|
||
| **Chi phí đảo ngược** | Trung bình — đổi sang canary sau này là bổ sung, không phải viết lại từ đầu |
|
||
|
||
### PA-3 — Canary (progressive traffic shifting)
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Mô tả** | Chuyển traffic dần theo tỷ lệ % (VD 10% → 50% → 100%) sang phiên bản mới, theo dõi metrics ở mỗi bước |
|
||
| **Ưu** | Phát hiện lỗi sớm hơn với blast radius nhỏ hơn (chỉ % nhỏ traffic chạm phiên bản lỗi) |
|
||
| **Nhược** | Thêm độ phức tạp giám sát (theo dõi metrics theo từng bước %, quyết định tự động/thủ công tiếp tục hay rollback ở mỗi bước) mà đội chưa có kinh nghiệm (`CON-05`); lợi ích thêm (phát hiện sớm hơn blue-green) chưa cần thiết ở quy mô tải hiện tại (kịch bản A/B của `TCO`) |
|
||
| **Chi phí đảo ngược** | Trung bình-cao — cấu hình canary phức tạp hơn, tháo dỡ cũng tốn công hơn |
|
||
|
||
### Bảng so sánh
|
||
|
||
| Tiêu chí | PA-1 | PA-2 | PA-3 |
|
||
|---|---|---|---|
|
||
| Downtime mỗi lần deploy | Cửa sổ ngắn (vài giây) | 0 theo thiết kế | 0 theo thiết kế |
|
||
| Tương thích `QAS-007` (ngân sách lỗi chặt) | 🔴 Rủi ro tích luỹ | ✅ | ✅ |
|
||
| Tốc độ rollback | Chậm (redeploy) | Tức thời (chuyển traffic) | Tức thời từng bước |
|
||
| Độ phức tạp vận hành so với năng lực đội hiện tại (`CON-05`) | Thấp | Trung bình | Cao |
|
||
|
||
## 3. Quyết định
|
||
|
||
> **Chọn PA-2 — Blue-green qua AWS CodeDeploy cho cả 3 dịch vụ ECS (Nhóm Giao dịch, Nhóm Hỗ trợ,
|
||
> Payment).**
|
||
|
||
**Vì sao:** Đây là phương án cân bằng tốt nhất giữa việc bảo vệ ngân sách lỗi chặt (`QAS-007`) và
|
||
độ phức tạp vận hành phù hợp với năng lực đội hiện tại (`CON-05`) — mạnh hơn rolling (không có
|
||
cửa sổ mất traffic), đơn giản hơn canary (không cần giám sát theo từng bước %).
|
||
|
||
**Phạm vi áp dụng:** Cả 3 dịch vụ ECS triển khai (Nhóm Giao dịch, Nhóm Hỗ trợ, Payment) — thống
|
||
nhất một chiến lược, không mỗi module một kiểu.
|
||
|
||
### Điều kiện chuyển `Proposed → Accepted`
|
||
|
||
| Điều kiện | Ai xác nhận | Trạng thái hiện tại |
|
||
|---|---|---|
|
||
| Ops/SRE xác nhận năng lực vận hành CodeDeploy (đào tạo nếu cần) | Ops/SRE | Mở (`OQ-008` đội Ops thật chưa xác nhận) |
|
||
| Chạy thử blue-green + rollback thành công ít nhất 1 lần ở staging | Ops/SRE | Chưa chạy |
|
||
| PO xác nhận số cuối cửa sổ bảo trì loại trừ ngân sách lỗi (`OQ-020`) | PO | Mở |
|
||
|
||
## 4. Phương án bị loại và lý do
|
||
|
||
| Phương án | Loại vì | Gắn với | Điều kiện nào thì xét lại |
|
||
|---|---|---|---|
|
||
| PA-1 — Rolling update | Cửa sổ mất traffic ngắn mỗi lần deploy tích luỹ có nguy cơ ăn vào ngân sách lỗi chặt `QAS-007` (43 phút/tháng); rollback chậm hơn | `QAS-007` | Không xét lại trừ khi `QAS-007` được PO hạ mức (nới ngân sách lỗi) — quyết định nghiệp vụ, không phải kỹ thuật |
|
||
| PA-3 — Canary | Thêm độ phức tạp giám sát/vận hành mà đội chưa có kinh nghiệm (`CON-05`); lợi ích thêm (blast radius nhỏ hơn) chưa cần thiết ở quy mô tải hiện tại | `CON-05` | Xét lại khi tải tăng đáng kể (vượt kịch bản B ×2 theo `SAD §10`) hoặc đội xác nhận đủ năng lực vận hành canary |
|
||
|
||
## 5. Hệ quả
|
||
|
||
**Hệ quả tích cực**
|
||
|
||
- Bảo vệ ngân sách lỗi `QAS-007` — 0 downtime theo thiết kế nếu health check đúng
|
||
- Rollback tức thời (giây) khi phát hiện lỗi sau khi đã chuyển traffic
|
||
|
||
**Hệ quả tiêu cực phải sống chung**
|
||
|
||
- Cần double capacity tạm thời trong cửa sổ chuyển đổi (cả blue lẫn green) — tăng chi phí nhỏ,
|
||
ngắn hạn, cần xác nhận không đáng kể so với `TCO`
|
||
- Đội cần đào tạo vận hành CodeDeploy nếu chưa có kinh nghiệm (`TCO §5`)
|
||
|
||
**Cái quyết định này khoá lại**
|
||
|
||
| Muốn đổi về sau thì | Tốn |
|
||
|---|---|
|
||
| Đổi sang canary sau này | Bổ sung cấu hình giám sát theo bước %, không phải viết lại toàn bộ pipeline — chi phí trung bình |
|
||
|
||
**Việc phát sinh**
|
||
|
||
| Việc | Chủ | Hạn | Ghi ở đâu |
|
||
|---|---|---|---|
|
||
| Cấu hình CodeDeploy thật cho cả 3 service | Ops/SRE (GĐ3) | Trước go-live | `03-enablement/AGD_e-commerce.md` (chưa tồn tại) |
|
||
| Viết runbook rollback chi tiết | Ops/SRE (GĐ3) | Trước go-live | `03-enablement/AGD_e-commerce.md` |
|
||
| Chạy thử blue-green + rollback ở staging | Ops/SRE | Trước AG2 | `INF §11 FIT-37` |
|
||
|
||
## 6. Cách kiểm chứng quyết định này được tuân thủ
|
||
|
||
| Cách kiểm | Công cụ | Chạy ở đâu | `FIT` |
|
||
|---|---|---|---|
|
||
| Blue-green deploy tự động rollback khi health check fail sau khi chuyển traffic | CodeDeploy hook test | Staging, trước mỗi major release | `FIT-37` *(đã đề xuất ở `INF §11`)* |
|
||
| Đo downtime thực tế trong 1 lần deploy blue-green, xác nhận = 0 (hoặc dưới ngưỡng nhỏ chấp nhận được) | Load test liên tục trong lúc deploy | Staging | Ứng viên bổ sung, cùng nhóm `FIT-37` |
|
||
|
||
## 7. Điều kiện xét lại
|
||
|
||
| Dấu hiệu | Ngưỡng | Ai theo dõi |
|
||
|---|---|---|
|
||
| Tần suất release tăng đáng kể, cần giảm blast radius hơn nữa | Release > vài lần/tuần với rủi ro cao (đề xuất, chưa xác nhận) | Tech Lead |
|
||
| Chi phí double-capacity trong cửa sổ deploy vượt ngân sách đáng kể | Vượt >5% chi phí compute hàng tháng (đề xuất, chưa xác nhận) | Ops/PO |
|
||
|
||
## 8. Tham chiếu
|
||
|
||
- POC: Không bắt buộc (radar 6/10, dưới ngưỡng 8)
|
||
- Bài đo: `FIT-37` (ứng viên GĐ3, đã đề xuất ở `INF §11`)
|
||
- Tài liệu ngoài: —
|
||
- Thảo luận: `INF_e-commerce_v1.0.md §6.4, §7.2` (phát hiện + đề xuất), `DEC-30` (duyệt từng phần)
|