# ADR-069: 基礎設施重建 Sprint B — ArgoCD GitOps 部署模式

**狀態**: Accepted  
**日期**: 2026-04-11 (台北時間)  
**作者**: Claude Sonnet 4.6 + 首席架構師審查  
**關聯**: Sprint B (ADR-069), `docs/superpowers/specs/2026-04-10-infra-rebuild-sprint-abc-design.md`

---

## 問題

CD pipeline 直接使用 `kubectl set image` 更新 K8s Deployment，與 ArgoCD 的 `selfHeal` 機制衝突：
- ArgoCD 偵測到 Git 狀態 ≠ K8s 狀態時自動 revert
- 無法追蹤部署歷史（誰在何時部署了什麼 image tag）
- kustomization.yaml 中的 `IMAGE_TAG_PLACEHOLDER` 從未真正更新到 Git

## 決定

採用 **ArgoCD GitOps 模式**：

```
CD Pipeline:
  Build → Push to Harbor
  → kustomize edit set image（更新 kustomization.yaml）
  → git commit [skip ci] + push to Gitea
  → ArgoCD 偵測 Git 變更，自動 sync
  → 等待 ArgoCD Synced + Healthy
  → kubectl rollout status 確認
  → Health Check
```

## 架構

### ArgoCD Application (`k8s/argocd/awoooi-prod-app.yaml`)

| 設定 | 值 | 說明 |
|------|-----|------|
| `automated.prune` | true | 刪除 Git 已移除的資源 |
| `automated.selfHeal` | true | 防止直接 kubectl 操作污染 |
| `syncOptions.ServerSideApply` | true | 支援大型 CRD |
| `ignoreDifferences` | Deployment/Secret | image tag 和 secrets 由 CD 管理 |

### 循環觸發防護

CD pipeline 的 kustomization.yaml 更新 commit 使用 `[skip ci]` 標記，
Gitea Actions 原生支援此標記，不會觸發新的 CD run。

### 新增 Secret

`CD_PUSH_TOKEN`: Gitea Personal Access Token，用於 CD pipeline push kustomization.yaml  
- 建立：Gitea → Settings → Applications → Generate Token  
- 權限：`write:repository`  
- 加到 Gitea Repository Secrets: Settings → Secrets → Add Secret

## 影響

### 正面

- **完整 GitOps 閉環**：所有部署變更都有 Git commit 記錄
- **防止 Configuration Drift**：ArgoCD selfHeal 確保 K8s = Git
- **可回滾**：`git revert` kustomization.yaml commit 即可回滾

### 注意事項

- `secrets.CD_PUSH_TOKEN` 需手動在 Gitea 建立並設定
- CD pipeline 現在有 `git push` 操作，需確保 runner 有網路存取 Gitea (192.168.0.110:3001)
- ArgoCD `ignoreDifferences` 排除 Deployment image 欄位，否則 ArgoCD 會顯示 OutOfSync

## 設定清單

- [ ] 在 Gitea 建立 Personal Access Token（write:repository 權限）
- [ ] 加到 Gitea Repository Secrets: `CD_PUSH_TOKEN`
- [ ] 確認 ArgoCD Application 已建立：`kubectl get app awoooi-prod -n argocd`
- [ ] 確認 ArgoCD 可存取 Gitea：檢查 ArgoCD Repo Server 網路策略
