unlock unlimited code runs for $79, limited time →
NOSSLETTER.techLIVE
back to OSSpedia
configuration-management

fix: add service for application controller statefulset (#29498)

Project: argoproj/argo-cd | Language: Go / YAML | Concepts: configuration-management | Difficulty: junior
Link: https://github.com/argoproj/argo-cd/pull/29499

The problem

The Argo CD Application Controller is deployed as a Kubernetes StatefulSet, which expects a headless Service to exist for stable network identities and peer discovery. However, the manifests were missing this Service, which could break networking for the StatefulSet and cause issues with pod communication or service discovery.

Why it's non-trivial

A naive fix might simply add a regular Service, but StatefulSets require a headless Service (clusterIP: None) with proper selectors to provide DNS for each pod. Omitting this or misconfiguring the Service could result in broken StatefulSet networking, non-unique pod hostnames, or failures in inter-pod communication.

The approach

1. Define the headless Service manifest

A new manifest is added to define the required Service. Notice the use of clusterIP: None (making it headless), and the selector matches the application-controller pods:

+apiVersion: v1
+kind: Service
+metadata:
+  labels:
+    app.kubernetes.io/component: application-controller
+    app.kubernetes.io/name: argocd-application-controller
+    app.kubernetes.io/part-of: argocd
+  name: argocd-application-controller
+spec:
+  clusterIP: None
+  selector:
+    app.kubernetes.io/name: argocd-application-controller

This ensures the Service is headless and only targets the correct pods.

2. Include the Service in the Kustomization base

The new Service manifest is added to the list of resources in the Kustomize base for the application controller:

-resources:
-- ../application-controller-roles
-- argocd-application-controller-statefulset.yaml
+- argocd-application-controller-service.yaml
- argocd-metrics.yaml
- argocd-application-controller-network-policy.yaml

This makes sure any installation using the base will include the Service.

3. Regenerate all installation bundles to include the Service

All installation YAMLs (standard, core, HA, namespaced, with/without hydrator) are updated to include the new Service. Example snippet from one of the bundles:

+apiVersion: v1
+kind: Service
+metadata:
+  labels:
+    app.kubernetes.io/component: application-controller
+    app.kubernetes.io/name: argocd-application-controller
+    app.kubernetes.io/part-of: argocd
+  name: argocd-application-controller
+spec:
+  clusterIP: None
+  selector:
+    app.kubernetes.io/name: argocd-application-controller

This ensures that every installation method now deploys the required Service.

4. Update test manifest count

A test is updated to expect one more manifest, reflecting the addition:

-	const countOfManifests = 50
+	const countOfManifests = 51

This keeps the test suite in sync with the manifest changes.

From the review thread

No notable review discussion on this PR.

Takeaways

  • Always match Kubernetes resource requirements to controller expectations. If a StatefulSet expects a headless Service, ensure it exists and is correctly configured.
  • Update all deployment variants when changing shared infrastructure. When a base manifest changes, regenerate all installation bundles to keep them consistent.
  • Keep automated tests in sync with configuration changes. If the number of manifests changes, update tests to reflect the new state to avoid false negatives.