Skip to content
obeyda@portfolio: ~/portfolio/workmain
Back to work
/ completed · 2023–2024

Moving a live Kubernetes platform to GitOps incrementally

An incremental GitOps migration that transferred ownership from deployment pipelines to Argo CD without a flag-day cutover.

Argo CDApplicationSetKubernetesHelmVaultExternal Secrets Operator

The migration was about ownership

Before Argo CD became authoritative, deployment pipelines controlled Kubernetes delivery. They rendered or applied Helm releases directly, and operators intervened when the running state diverged from what the pipeline expected.

The challenge was transferring live resources without letting both control paths write the same objects or forcing every team through one cutover.

A flag-day change would amplify any bad manifest, secret reference, or reconciliation setting. Bounded handoffs kept failures local.

Starting with platform dependencies

Platform dependencies moved first because their ownership was clear and the platform team understood them. The layer grew to include ingress, certificates, external secrets, autoscaling, policy, rollout, and observability controllers.

Argo CD Applications handled independent components. ApplicationSets generated repeated deployments across environments or clusters without one oversized parent application.

An explicit handoff for each scope

One writer at every handoff
100%
Compare desired and live state, release the pipeline writer, then enable and verify Argo CD.

Scroll to zoom · drag to pan · arrow keys to pan · Escape to close

Compare desired and live state, release the pipeline writer, then enable and verify Argo CD.

One writer at every handoffCompare desired and live state, release the pipeline writer, then enable and verify Argo CD.

Old and new systems coexisted across the platform, never as competing writers for one resource.

Handling drift and secrets safely

Generated or runtime-owned fields were excluded when they were not actionable drift. Remaining differences were understood before self-healing was enabled.

Secrets stayed outside Git. Vault remained the source of secret material, with External Secrets Operator connecting that source to Kubernetes resources. Argo CD managed the declarative references and surrounding workloads, not plaintext secret values.

Git described deployment intent without turning the migration into a secret-management rewrite.

Expanding to application workloads

Application workloads followed after platform dependencies proved the pattern. Pipelines kept building artifacts; Git and Argo CD gained deployment authority scope by scope.

Teams kept delivering during the migration and changed workflows only when their workloads reached the handoff point.

Result

The platform reached a GitOps operating model without one disruptive cutover. Ownership became explicit, drift visible and bounded, and repeated delivery patterns consistent. Existing delivery remained available until each scope was ready.

Trade-offs

Temporary coexistence required a clear ownership inventory and more discipline than a one-time replacement. In return, explicit handoffs reduced blast radius and preserved application-team productivity.

Part of: Building Azure Landing Zones, Then Expanding Across Clouds

Related work:

All case studies