Skip to content

Commit b9b8325

Browse files
authored
Disable webhook admissions enforcer in AKS (#350)
1 parent 5818256 commit b9b8325

3 files changed

Lines changed: 65 additions & 0 deletions

File tree

charts/amazon-cloudwatch-observability/templates/admission-webhooks/operator-webhook-with-cert-manager.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ kind: MutatingWebhookConfiguration
44
metadata:
55
annotations:
66
cert-manager.io/inject-ca-from: {{ printf "%s/%s-serving-cert" .Release.Namespace (include "amazon-cloudwatch-observability.name" .) }}
7+
{{- if eq .Values.k8sMode "AKS" }}
8+
# Opt out of the AKS admissionsenforcer, which otherwise injects its own namespaceSelector into
9+
# each webhook and takes server-side-apply ownership of the field, causing helm upgrade to
10+
# conflict. See https://learn.microsoft.com/en-us/azure/aks/faq (admissions enforcer).
11+
admissions.enforcer/disabled: "true"
12+
{{- end }}
713
labels:
814
{{- include "amazon-cloudwatch-observability.labels" . | nindent 4}}
915
name: {{ template "amazon-cloudwatch-observability.name" . }}-mutating-webhook-configuration
@@ -156,6 +162,12 @@ kind: ValidatingWebhookConfiguration
156162
metadata:
157163
annotations:
158164
cert-manager.io/inject-ca-from: {{ printf "%s/%s-serving-cert" .Release.Namespace (include "amazon-cloudwatch-observability.name" .) }}
165+
{{- if eq .Values.k8sMode "AKS" }}
166+
# Opt out of the AKS admissionsenforcer, which otherwise injects its own namespaceSelector into
167+
# each webhook and takes server-side-apply ownership of the field, causing helm upgrade to
168+
# conflict. See https://learn.microsoft.com/en-us/azure/aks/faq (admissions enforcer).
169+
admissions.enforcer/disabled: "true"
170+
{{- end }}
159171
labels:
160172
{{- include "amazon-cloudwatch-observability.labels" . | nindent 4}}
161173
name: {{ template "amazon-cloudwatch-observability.name" . }}-validating-webhook-configuration

charts/amazon-cloudwatch-observability/templates/admission-webhooks/operator-webhook.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ data:
1515
apiVersion: admissionregistration.k8s.io/v1
1616
kind: MutatingWebhookConfiguration
1717
metadata:
18+
{{- if eq .Values.k8sMode "AKS" }}
19+
annotations:
20+
# Opt out of the AKS admissionsenforcer, which otherwise injects its own namespaceSelector into
21+
# each webhook and takes server-side-apply ownership of the field, causing helm upgrade to
22+
# conflict. See https://learn.microsoft.com/en-us/azure/aks/faq (admissions enforcer).
23+
admissions.enforcer/disabled: "true"
24+
{{- end }}
1825
labels:
1926
{{- include "amazon-cloudwatch-observability.labels" . | nindent 4}}
2027
name: {{ template "amazon-cloudwatch-observability.name" . }}-mutating-webhook-configuration
@@ -170,6 +177,13 @@ webhooks:
170177
apiVersion: admissionregistration.k8s.io/v1
171178
kind: ValidatingWebhookConfiguration
172179
metadata:
180+
{{- if eq .Values.k8sMode "AKS" }}
181+
annotations:
182+
# Opt out of the AKS admissionsenforcer, which otherwise injects its own namespaceSelector into
183+
# each webhook and takes server-side-apply ownership of the field, causing helm upgrade to
184+
# conflict. See https://learn.microsoft.com/en-us/azure/aks/faq (admissions enforcer).
185+
admissions.enforcer/disabled: "true"
186+
{{- end }}
173187
labels:
174188
{{- include "amazon-cloudwatch-observability.labels" . | nindent 4}}
175189
name: {{ template "amazon-cloudwatch-observability.name" . }}-validating-webhook-configuration

integration-tests/amazon-cloudwatch-observability/validations/minikube/scenarios/aks_otel_container_insights_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ func TestAKSOtelContainerInsights(t *testing.T) {
7373
t.Run("OTELConfigRouting", func(t *testing.T) {
7474
validateOTELConfigRoutingAKS(t, agentMap)
7575
})
76+
t.Run("WebhookEnforcerDisabled", func(t *testing.T) {
77+
validateAKSWebhookEnforcerDisabled(t, k8sClient)
78+
})
7679

7780
t.Log("AKS OTEL Container Insights scenario validation passed")
7881
}
@@ -197,3 +200,39 @@ func validateAKSHostAttributes(t *testing.T, agentMap map[string]unstructured.Un
197200
assertEnabled("node agent", otelConfigOf(t, agentMap, "cloudwatch-agent"), true)
198201
assertEnabled("cluster-scraper", otelConfigOf(t, agentMap, "cloudwatch-agent-cluster-scraper"), false)
199202
}
203+
204+
// validateAKSWebhookEnforcerDisabled checks the webhook configurations carry the
205+
// admissions.enforcer/disabled annotation on AKS. Without it, the AKS admissionsenforcer rewrites each
206+
// webhook's namespaceSelector and takes server-side-apply ownership of the field, which makes the next
207+
// helm upgrade fail with an apply conflict.
208+
func validateAKSWebhookEnforcerDisabled(t *testing.T, k8sClient *util.K8sClient) {
209+
const enforcerDisabled = "admissions.enforcer/disabled"
210+
211+
mwc, err := k8sClient.ListMutatingWebhookConfigurations()
212+
require.NoError(t, err, "failed to list MutatingWebhookConfigurations")
213+
assertEnforcerDisabled := func(name string, annotations map[string]string) {
214+
assert.Equal(t, "true", annotations[enforcerDisabled],
215+
"%s should set %s on AKS", name, enforcerDisabled)
216+
}
217+
218+
foundMutating := false
219+
for _, wh := range mwc.Items {
220+
if wh.Name == minikube.WebhookName {
221+
foundMutating = true
222+
assertEnforcerDisabled(wh.Name, wh.Annotations)
223+
}
224+
}
225+
assert.True(t, foundMutating, "mutating webhook configuration %s should exist", minikube.WebhookName)
226+
227+
vwc, err := k8sClient.ListValidatingWebhookConfigurations()
228+
require.NoError(t, err, "failed to list ValidatingWebhookConfigurations")
229+
validatingName := "amazon-cloudwatch-observability-validating-webhook-configuration"
230+
foundValidating := false
231+
for _, wh := range vwc.Items {
232+
if wh.Name == validatingName {
233+
foundValidating = true
234+
assertEnforcerDisabled(wh.Name, wh.Annotations)
235+
}
236+
}
237+
assert.True(t, foundValidating, "validating webhook configuration %s should exist", validatingName)
238+
}

0 commit comments

Comments
 (0)