You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .github/instructions/standards.instructions.md
+13-1Lines changed: 13 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,7 +33,7 @@ Applications are categorized into `infrastructure`, `monitoring`, and `my-apps`,
33
33
- `CreateNamespace=true`
34
34
- `ServerSideApply=true`
35
35
- `RespectIgnoreDifferences=true`
36
-
- `ApplyOutOfSyncOnly=true`
36
+
- `Replace=false`
37
37
- Retry: exponential backoff, max 5 attempts, 3m cap
38
38
39
39
## ApplicationSet: `monitoring`
@@ -74,6 +74,18 @@ Applications are categorized into `infrastructure`, `monitoring`, and `my-apps`,
74
74
- All apps must support `kustomize build` locally
75
75
- Use `ignoreDifferences` for Helm-managed labels, CRDs, and known noisy fields
76
76
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
6. **Completion**: The process continues until all waves are healthy.
95
95
96
96
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.
0 commit comments