GitOps Promoter: Promote môi trường không còn là cơn ác mộng
Tool mới từ argoproj-labs giúp tự động hóa việc promote code qua các môi trường theo đúng tinh thần GitOps không fragile scripts, không manual mess.
Nguyễn Nhật Long
@nguyennhatlong1303
Nếu bạn đang dùng ArgoCD hay bất kỳ GitOps tool nào, chắc chắn bạn đã từng đau đầu với bài toán này: làm sao để promote một commit từ dev lên staging, rồi từ staging lên prod một cách tự động, an toàn, và có kiểm soát?
Mình đã trải qua đủ kiểu giải pháp từ shell script chạy git cherry-pick rồi push lên, đến dùng CI pipeline tự merge branch, rồi cả kiểu dùng Kustomize overlays với GitHub Actions tự động update image tag. Cái nào cũng có vấn đề. Không phải fragile thì cũng thiếu visibility, hoặc khó maintain khi team lớn dần.
Rồi mình tìm thấy gitops-promoter từ argoproj-labs. Cái project này giải quyết đúng cái pain point đó và theo một cách khá thú vị.
Vấn đề thực sự của environment promotion trong GitOps
Trước khi nói về tool, mình muốn nói rõ vấn đề một chút, vì nhiều người hay bỏ qua phần này.
Trong GitOps, Git là source of truth. Mỗi môi trường thường map với một branch hoặc một thư mục trong repo. Khi bạn muốn promote tức là đưa một thay đổi từ môi trường này sang môi trường khác về cơ bản bạn đang merge hoặc copy một commit từ branch này sang branch khác.
Nghe đơn giản. Nhưng thực tế thì không:
- Bạn cần đảm bảo commit đó đã thực sự healthy ở môi trường nguồn trước khi promote lên
- Bạn cần có cơ chế gate ví dụ: security scan phải pass, performance test phải xanh, không có deployment freeze
- Bạn cần audit trail ai promote cái gì, khi nào, tại sao
- Bạn cần tránh drift không phải cứ merge là xong, bạn cần đảm bảo trạng thái thực tế khớp với những gì trong Git
Các giải pháp tự chế thường handle được 1-2 điểm trong số này. gitops-promoter nhắm đến việc giải quyết tất cả.
Cách gitops-promoter hoạt động
Project này chạy như một Kubernetes controller (theo đúng pattern của Argo ecosystem). Bạn define promotion strategy bằng CRD, và controller sẽ lo phần còn lại.
Core concept có 3 phần chính:
1. Branch-based environments Mỗi môi trường là một branch trong Git repo của bạn, ví dụ environment/dev, environment/staging, environment/prod.
2. Commit Statuses Đây là cơ chế gate. Thay vì hardcode điều kiện promote, bạn dùng commit status (giống như CI status trên GitHub/GitLab) để signal rằng một commit đã sẵn sàng. Controller sẽ watch các status này và chỉ promote khi đủ điều kiện.
3. Pull Request-based promotion Thay vì tự động push thẳng vào branch đích, tool tạo PR. Điều này cho phép bạn có review process, audit trail, và integrate với các SCM workflow sẵn có.
Mình thấy cái approach dùng PR này khá hay. Nó không phải là "automated changes to user-facing files" bạn vẫn thấy được chính xác cái gì đang được promote, và có thể can thiệp nếu cần.
Setup cơ bản
Project hiện đang ở trạng thái experimental, nhưng cấu trúc CRD khá rõ ràng. Đây là một ví dụ PromotionStrategy đầy đủ:
1apiVersion: promoter.argoproj.io/v1alpha12kind: PromotionStrategy3metadata:4 name: my-app-promotion5 namespace: gitops-promoter6spec:7 gitRepositoryRef:8 name: my-app-repo9 # Commit statuses phải có trên commit đang active (đã deploy)10 activeCommitStatuses:11 - key: argocd-app-health12 # Commit statuses phải có trên commit đang proposed (chưa deploy)13 proposedCommitStatuses:14 - key: security-scan15 environments:16 - branch: environment/dev17 - branch: environment/staging18 - branch: environment/prod19 autoMerge: false # prod thì require manual approval20 activeCommitStatuses:21 - key: performance-test22 proposedCommitStatuses:23 - key: deployment-freeze
Bạn cũng cần define GitRepository để controller biết repo nào cần watch:
1apiVersion: promoter.argoproj.io/v1alpha12kind: GitRepository3metadata:4 name: my-app-repo5 namespace: gitops-promoter6spec:7 github:8 domain: github.com9 owner: my-org10 name: my-app-config11 secretRef:12 name: github-token
Và secret chứa GitHub token:
1apiVersion: v12kind: Secret3metadata:4 name: github-token5 namespace: gitops-promoter6type: Opaque7stringData:8 token: ghp_xxxxxxxxxxxx
Commit Status là trái tim của hệ thống
Phần này mình muốn đi sâu hơn vì nó là điểm khác biệt lớn nhất so với các approach khác.
gitops-promoter phân biệt hai loại commit status:
Sự phân biệt này rất quan trọng. Ví dụ: bạn muốn đảm bảo commit ở dev đã thực sự healthy (active status) trước khi promote lên staging. Đồng thời, commit sắp được đưa vào staging cũng phải pass security scan (proposed status).
| Loại | Ý nghĩa | Ví dụ use case |
|---|---|---|
| `activeCommitStatuses` | Check trên commit đang **chạy thực tế** ở môi trường | ArgoCD app health, smoke test sau deploy |
| `proposedCommitStatuses` | Check trên commit **sắp được promote** | Security scan, lint, unit test, deployment freeze check |
Các status này được set từ bên ngoài có thể là CI pipeline, có thể là một custom controller khác, hoặc thậm chí là một script đơn giản gọi GitHub API:
1# Ví dụ: CI pipeline set commit status sau khi security scan xong2curl -X POST \3 -H "Authorization: token $GITHUB_TOKEN" \4 -H "Accept: application/vnd.github.v3+json" \5 https://api.github.com/repos/my-org/my-app-config/statuses/$COMMIT_SHA \6 -d '{7 "state": "success",8 "context": "security-scan",9 "description": "Trivy scan passed - no critical CVEs"10 }'
Cái hay ở đây là bạn không bị lock in vào bất kỳ CI tool nào. Miễn là có thể set commit status lên GitHub/GitLab, là integrate được.
So sánh với các approach phổ biến
Mình đã thử qua khá nhiều cách handle promotion, đây là góc nhìn thực tế:
Theo kinh nghiệm của mình, điểm yếu lớn nhất của các CI-based approach là chúng không biết gì về trạng thái thực tế của ứng dụng sau khi deploy. Chúng chỉ biết "pipeline đã chạy xong" chứ không biết "app có thực sự healthy không". gitops-promoter với activeCommitStatuses giải quyết đúng vấn đề này.
| Approach | Ưu điểm | Nhược điểm |
|---|---|---|
| CI pipeline tự push/merge | Đơn giản setup ban đầu | Fragile, khó debug khi fail, thiếu audit trail |
| Kustomize + image updater | Tự động update image tag | Chỉ handle image, không handle config changes |
| Manual PR | An toàn, có review | Chậm, tốn effort, không scale |
| Flux Image Automation | Tích hợp tốt với Flux | Chỉ dùng được nếu bạn đang dùng Flux |
| **gitops-promoter** | Drift-free, có gate system, PR-based | Còn experimental, cần Kubernetes để chạy |
Promotion flow thực tế trông như thế nào
Để hình dung rõ hơn, đây là một flow điển hình:
- Developer merge code vào
main - CI build image, push lên registry, rồi update
environment/devbranch với image tag mới (bước này vẫn do CI làm) - ArgoCD sync
environment/dev, deploy lên cluster dev - ArgoCD set
argocd-app-healthcommit status =successkhi app healthy - CI set
security-scancommit status =successcho commit sắp được promote lên staging - gitops-promoter phát hiện cả hai status đã green → tự động tạo PR từ
environment/devvàoenvironment/staging - PR được auto-merge (hoặc require manual review tùy config)
- Lặp lại cho staging → prod, nhưng prod có
autoMerge: falsenên cần người approve
Anh em lưu ý: bước 2 vẫn cần một cơ chế nào đó để update branch environment/dev gitops-promoter không handle phần "đưa code vào môi trường đầu tiên", nó chỉ handle phần "promote từ môi trường này sang môi trường khác".
Điểm cần cân nhắc trước khi adopt
Mình muốn thành thật: project này vẫn đang ở trạng thái experimental. Đây không phải lý do để bỏ qua, nhưng cần biết để set expectation đúng.
Một số thứ cần cân nhắc:
- Dependency: Bạn cần một Kubernetes cluster để chạy controller. Nếu team bạn không dùng Kubernetes thì đây không phải lựa chọn phù hợp.
- Git repo structure: Bạn cần adopt branch-per-environment pattern. Nếu hiện tại bạn đang dùng folder-per-environment trong cùng một branch, sẽ cần refactor.
- SCM integration: Hiện tại support GitHub và GitLab. Nếu bạn dùng Bitbucket hay Azure DevOps thì cần check lại docs.
- Learning curve: Concept của
activeCommitStatusesvsproposedCommitStatusescần thời gian để team hiểu và setup đúng.
Mình thấy cái này hay ở chỗ nó không cố gắng làm tất cả mọi thứ. Nó focus vào đúng một bài toán promotion và làm tốt bài toán đó. Các concern khác như "làm sao update image tag", "làm sao chạy test" vẫn là việc của CI pipeline bạn, gitops-promoter chỉ đọc kết quả từ commit status.
Thử local với Tilt
Nếu bạn muốn experiment trước khi commit vào production, project có sẵn Tiltfile để dev locally:
1# Clone repo2git clone https://github.com/argoproj-labs/gitops-promoter3cd gitops-promoter45# Cần có kind cluster hoặc local k8s6kind create cluster78# Chạy với Tilt9tilt up
Repo cũng có webrequestsimulator một tool để simulate các webhook event từ GitHub/GitLab, rất tiện cho việc test mà không cần setup real webhook.
Nhìn tổng thể, gitops-promoter đang giải quyết một bài toán thực sự quan trọng theo một cách có tư duy rõ ràng. Cái concept dùng commit status như một universal gate bất kể status đó đến từ ArgoCD, CI pipeline, hay custom check là một design decision khá elegant. Nó giữ cho controller đơn giản trong khi vẫn flexible với mọi use case.
Nếu team bạn đang dùng ArgoCD và đang đau đầu với promotion workflow, đây là một project đáng để bỏ thời gian evaluate. Mình sẽ tiếp tục theo dõi và có thể sẽ viết thêm khi project stable hơn.
Nguyễn Nhật Long
@nguyennhatlong1303Nguyễn Nhật Long is a Senior Frontend Engineer and Frontend Team Leader with 7 years of experience building real-time fintech platforms. Specializing in React, Next.js, TypeScript, and React Native, shipping 10+ products across Web, Mobile, Telegram Mini-Apps, and Web3.
Thấy hay? Chia sẻ cho bạn bè!