Velocity Stream LogoVelocity Stream Logo
Back to Insights
Kubernetes
GitOps
ArgoCD

Escaping YAML Hell: Scaling GitOps & ArgoCD for 50+ Microservices

How we eliminated configuration drift, automated deployments, and scaled ArgoCD across multi-region EKS clusters for a Series-B SaaS platform.

8 min read
Futuristic isometric server rack showing automated GitOps deployment streams

The Problem: Death by a Thousand YAML Files

GitOps promises an operational utopia: your Git repository is the single source of truth for your infrastructure. But for a rapidly growing Series-B SaaS client, that dream quickly turned into a nightmare of configuration drift and "YAML fatigue."

When they had 5 microservices, managing Kubernetes manifests manually was fine. By the time they hit 50 microservices across 4 environments (Dev, Staging, EU-Prod, US-Prod), they were maintaining over 1,500 YAML files.

The Breaking Point

Deployments were taking 45+ minutes. Developers were afraid to merge infrastructure PRs. Staging environments were constantly drifting from Production because developers would manually kubectl apply hotfixes and forget to update Git.

The Fix: Restructuring for "App of Apps"

We realized the issue wasn't ArgoCD—it was how they were using it. They had a single flat repository containing hundreds of Kustomize overlays. We executed a complete restructure using the App of Apps pattern and ApplicationSets.

1. Abstracting Complexity with Helm

First, we stopped developers from writing raw Kubernetes manifests. We created a single, standardized, internal Helm chart called saas-microservice-base. Instead of 10 different YAML files for Deployments, Services, Ingress, and HPA, developers only needed to write a 15-line values.yaml file.

2. Dynamic Deployments with ApplicationSets

Rather than manually registering 50 apps in ArgoCD, we implemented ArgoCD ApplicationSets. Using the Git generator, ArgoCD automatically discovers new microservices based on repository directory structures.

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cluster-workloads
spec:
  generators:
    - git:
        repoURL: https://github.com/org/gitops-repo.git
        revision: HEAD
        directories:
          - path: apps/*/overlays/production
  template:
    metadata:
      name: '{{path.basename}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/org/gitops-repo.git
        targetRevision: HEAD
        path: '{{path}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{path.basename}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true

3. Closing the Loop with Argo Image Updater

The final piece of the puzzle was deployment automation. We configured Argo Image Updater to watch the client's ECR registry. When a new Docker image passes CI tests and is pushed to ECR, the Image Updater automatically detects the semantic version tag, writes the new image tag back to the Git repository, and triggers ArgoCD to sync.

Before Velocity Stream

  • 45-minute manual deployment process
  • Constant drift between staging and prod
  • 1,500+ raw YAML files to maintain
  • Developers required K8s expertise

After Implementation

  • 3-minute automated deployments
  • Zero configuration drift (Self-healing active)
  • Standardized Helm abstraction
  • "Invisible" infrastructure for developers

The ROI of Platform Engineering

By shifting from a raw DevOps model to a true Platform Engineering approach, we didn't just fix a deployment pipeline; we recovered hundreds of engineering hours per month. Developers went back to writing features instead of fighting YAML formatting errors.

If your GitOps setup feels like it's slowing you down rather than speeding you up, it might be time to rethink your repository architecture.

Is your CI/CD pipeline holding you back?

Our senior engineers specialize in untangling complex deployments and scaling GitOps infrastructure for high-growth tech companies.

Chat with an Engineer