Skip to content

Commit e94c33e

Browse files
committed
fix argo
1 parent 7e57e9e commit e94c33e

8 files changed

Lines changed: 97 additions & 10 deletions

File tree

.github/instructions/argocd.instructions.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ Standard sync options for all applications:
7676
- `CreateNamespace=true`: Auto-create target namespaces
7777
- `ServerSideApply=true`: Use server-side apply for better conflict resolution
7878
- `RespectIgnoreDifferences=true`: Honor ignoreDifferences configurations
79-
- `ApplyOutOfSyncOnly=true`: Only apply resources that are out of sync
79+
- `Replace=false`: Use patch instead of full replace
80+
- **DO NOT use `ApplyOutOfSyncOnly=true`** — causes silent sync failures with SSA (configmaps not applied)
8081

8182
### Retry Strategy
8283
```yaml
@@ -211,8 +212,12 @@ kubectl describe application <app-name> -n argocd
211212
### Sync Policies
212213
- ✅ Use automated sync with prune and selfHeal
213214
- ✅ Set appropriate sync waves for dependencies
214-
- ✅ Use server-side apply for complex resources
215+
- ✅ Use server-side apply AND server-side diff together (both enabled globally)
216+
- ✅ Keep `RespectIgnoreDifferences=true` for PVC/HTTPRoute/ExternalSecret diffs
217+
- ❌ Don't use `ApplyOutOfSyncOnly=true` — causes silent sync failures with SSA
218+
- ❌ Don't use `IgnoreMissingTemplate=true` — masks real template errors
215219
- ❌ Don't disable automated sync without good reason
220+
- ❌ Don't use client-side diff with server-side apply (diff/apply mismatch)
216221

217222
### Resource Management
218223
- ✅ Use ignoreDifferences for known noisy fields

.github/instructions/standards.instructions.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Applications are categorized into `infrastructure`, `monitoring`, and `my-apps`,
3333
- `CreateNamespace=true`
3434
- `ServerSideApply=true`
3535
- `RespectIgnoreDifferences=true`
36-
- `ApplyOutOfSyncOnly=true`
36+
- `Replace=false`
3737
- Retry: exponential backoff, max 5 attempts, 3m cap
3838

3939
## ApplicationSet: `monitoring`
@@ -74,6 +74,18 @@ Applications are categorized into `infrastructure`, `monitoring`, and `my-apps`,
7474
- All apps must support `kustomize build` locally
7575
- Use `ignoreDifferences` for Helm-managed labels, CRDs, and known noisy fields
7676

77+
# Server-Side Diff & Apply (CRITICAL)
78+
79+
This cluster uses **Server-Side Diff** globally (`resource.server-side-diff: "true"` in `argocd-cm`) paired with **Server-Side Apply** (`ServerSideApply=true` in syncOptions). These MUST be aligned:
80+
81+
- **Server-Side Apply** sends manifests to K8s API for patching with field ownership tracking
82+
- **Server-Side Diff** asks K8s API "what would change?" via dry-run SSA, then compares the result
83+
- Without Server-Side Diff, ArgoCD uses client-side diff which guesses — and can miss changes that SSA would detect (especially ConfigMap data), causing resources to silently not get applied
84+
85+
**Forbidden sync options:**
86+
- `ApplyOutOfSyncOnly=true` — relies on diff accuracy; with SSA edge cases, resources can be skipped silently
87+
- `IgnoreMissingTemplate=true` — masks template rendering errors in ApplicationSets
88+
7789
# Helm + Kustomize Integration
7890

7991
Refer to `1password-connect` as a pattern:

docs/argocd.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,76 @@ resource.customizations.health.argoproj.io_Application: |
9494
6. **Completion**: The process continues until all waves are healthy.
9595

9696
This ensures a deterministic, reliable boot sequence every time.
97+
98+
## Server-Side Diff vs Client-Side Diff
99+
100+
This cluster uses **Server-Side Diff** (`resource.server-side-diff: "true"` in `argocd-cm`) paired with **Server-Side Apply** (`ServerSideApply=true` in syncOptions). These must be aligned — using one without the other causes silent sync failures.
101+
102+
### Client-Side Diff (legacy, DO NOT USE with SSA)
103+
104+
ArgoCD downloads the live resource from the cluster, then compares it against the Git manifest **locally in the ArgoCD controller**. It's essentially doing `diff manifest.yaml live-resource.yaml` on its own.
105+
106+
**Problem**: ArgoCD doesn't know what Kubernetes would actually do with the manifest. Kubernetes adds defaults, mutating webhooks modify fields, and SSA has field ownership rules. ArgoCD is guessing — and sometimes guesses wrong (thinks it's "in-sync" when it's not).
107+
108+
### Server-Side Diff (modern, REQUIRED with SSA)
109+
110+
ArgoCD sends the Git manifest to the Kubernetes API as a **dry-run server-side apply** and gets back what the result *would* look like. Then it compares *that* against the live resource.
111+
112+
**Why it's better**: Kubernetes itself tells ArgoCD "here's what would change if you applied this" — accounting for defaults, field ownership, webhooks, everything. No guessing.
113+
114+
### Why the Mismatch Breaks ConfigMaps
115+
116+
Without Server-Side Diff, using Server-Side Apply + `ApplyOutOfSyncOnly`:
117+
118+
```
119+
Git: configmap data = NEW content
120+
121+
Client-side diff: "managed fields metadata looks the same..." → IN SYNC (wrong!)
122+
123+
ApplyOutOfSyncOnly: "it's in-sync, skip it"
124+
125+
Result: configmap never applied, ArgoCD says "Synced" ✓ (LIE)
126+
```
127+
128+
With Server-Side Diff:
129+
130+
```
131+
Git: configmap data = NEW content
132+
133+
K8s API dry-run: "this would change .data.presets.ini" → OUT OF SYNC
134+
135+
Sync: applies the configmap
136+
137+
Result: configmap actually updated ✓
138+
```
139+
140+
### Configuration
141+
142+
Enabled globally in `infrastructure/controllers/argocd/values.yaml`:
143+
144+
```yaml
145+
configs:
146+
cm:
147+
resource.server-side-diff: "true"
148+
```
149+
150+
### Sync Options (CRITICAL — do not add ApplyOutOfSyncOnly)
151+
152+
Standard sync options for all ApplicationSets:
153+
154+
```yaml
155+
syncOptions:
156+
- CreateNamespace=true
157+
- ServerSideApply=true # Server-side apply for better conflict resolution
158+
- RespectIgnoreDifferences=true # Honor ignoreDifferences for PVC, HTTPRoute, etc.
159+
- Replace=false # Use patch, not full replace
160+
```
161+
162+
**DO NOT add these options:**
163+
- `ApplyOutOfSyncOnly=true` — Even with ServerSideDiff, has [known edge cases with key removal](https://github.com/argoproj/argo-cd/issues/24882). Not worth the risk for a homelab-scale cluster.
164+
- `IgnoreMissingTemplate=true` — Can mask real template errors in ApplicationSets.
165+
166+
### References
167+
- [ArgoCD Diff Strategies](https://argo-cd.readthedocs.io/en/stable/user-guide/diff-strategies/)
168+
- [ArgoCD SSA ConfigMap sync failure (#22687)](https://github.com/argoproj/argo-cd/issues/22687)
169+
- [ArgoCD key removal not detected (#24882)](https://github.com/argoproj/argo-cd/issues/24882)

infrastructure/controllers/argocd/apps/infrastructure-appset.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,7 @@ spec:
6060
- CreateNamespace=true
6161
- ServerSideApply=true
6262
- RespectIgnoreDifferences=true
63-
- ApplyOutOfSyncOnly=true
6463
- Replace=false
65-
- IgnoreMissingTemplate=true
6664
retry:
6765
limit: 5
6866
backoff:

infrastructure/controllers/argocd/apps/monitoring-appset.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@ spec:
3636
- CreateNamespace=true
3737
- ServerSideApply=true
3838
- RespectIgnoreDifferences=true
39-
- ApplyOutOfSyncOnly=true
4039
- Replace=false
41-
- IgnoreMissingTemplate=true
4240
retry:
4341
limit: 5
4442
backoff:

infrastructure/controllers/argocd/apps/my-apps-appset.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@ spec:
3636
- CreateNamespace=true
3737
- ServerSideApply=true
3838
- RespectIgnoreDifferences=true
39-
- ApplyOutOfSyncOnly=true
4039
- Replace=false
41-
- IgnoreMissingTemplate=true
4240
retry:
4341
limit: 5
4442
backoff:

infrastructure/controllers/argocd/root.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ spec:
2222
- CreateNamespace=true
2323
- ServerSideApply=true
2424
- RespectIgnoreDifferences=true
25-
- ApplyOutOfSyncOnly=true
2625
ignoreDifferences:
2726
- group: argoproj.io
2827
kind: Application

infrastructure/controllers/argocd/values.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ configs:
1818
cm:
1919
url: "https://argocd.vanillax.me"
2020
kustomize.buildOptions: "--enable-helm"
21+
# Use server-side diff to match ServerSideApply - prevents false "in-sync" detection
22+
# Without this, client-side diff + server-side apply disagree on changes, causing
23+
# configmaps and other resources to silently not get applied
24+
resource.server-side-diff: "true"
2125
# Performance: add jitter to prevent all 60+ apps reconciling simultaneously
2226
timeout.reconciliation: "60s"
2327
timeout.reconciliation.jitter: "30s"

0 commit comments

Comments
 (0)