Cloud

GitOps at Scale: Running Argo CD Beyond the First Cluster

TuniCyberLabs Team
7 min read

How to structure repositories, reconciliation, secrets, and promotion so GitOps still works when you pass your third Kubernetes cluster.

Every team's first Argo CD installation looks the same: one cluster, one repository, a dozen Applications, and a satisfying wall of green sync statuses. GitOps — driving cluster state from declarative configuration in Git, continuously reconciled by an in-cluster controller — genuinely delivers at that scale. The trouble begins around cluster number three, when repository sprawl, sync storms, and secret handling start turning the green wall amber.

Scaling GitOps is less about the controller you pick — Argo CD and Flux are both CNCF-graduated and both capable — and more about the decisions around it: repository structure, reconciliation behavior, secrets, and promotion. Get those wrong early and you pay a migration tax for years, because configuration repositories accumulate consumers faster than any codebase.

Repository Layout Is an Architecture Decision

The first fork in the road is monorepo versus per-team repositories. A single configuration monorepo gives you atomic cross-service changes and one audit surface, but every merge fans out webhooks across the fleet and the CODEOWNERS file becomes an organizational bottleneck. Per-team repositories scale review and access control cleanly, but a platform-wide change — a new admission policy, a base image bump — becomes a coordination exercise across dozens of pull requests.

The hybrid usually wins: a platform repository owning cluster add-ons, policies, and shared Helm chart versions, plus per-team application repositories discovered dynamically through Argo CD ApplicationSets or per-tenant Flux Kustomizations. One rule matters more than the layout itself: rendered manifests must be diffable in the pull request. If reviewers cannot see the concrete YAML delta because a chart version bump silently rewrites a hundred resources, you have lost the central safety property GitOps promised. Rendered-manifest pipelines, where CI commits fully hydrated YAML into environment directories, are worth the extra plumbing at fleet scale.

Keep Reconciliation Boring

At thirty Applications the reconciliation loop is invisible. At three hundred it becomes a performance and correctness concern in its own right:

  • Shard the controllers: run multiple application controller replicas sharded by destination cluster, or one busy cluster will starve status updates for the rest of the fleet.
  • Be selective with self-heal: automated sync with self-heal and prune is right for stateless workloads; for CRDs and operators, prefer manual gates or sync windows so a bad merge cannot cascade across every cluster in seconds.
  • Order with sync waves: apply CRDs before the operators that consume them, and write custom health checks for your own resources so the dashboard does not report Healthy while a controller is crash-looping.
  • Prefer webhooks to polling: the default three-minute poll across hundreds of Applications hammers your Git provider; use webhooks with a jittered fallback interval as the safety net.

Secrets Without Breaking the Model

Plaintext secrets in Git are obviously out; the real question is where decryption happens. Sealed Secrets keeps everything in the repository but binds ciphertext to a per-cluster key, which makes cluster rebuilds and disaster recovery painful. SOPS with age or a cloud KMS keeps encrypted values in Git and decrypts at reconcile time — Flux supports this natively. The External Secrets Operator inverts the model entirely: Git stores only references, and the actual values live in Vault, AWS Secrets Manager, or Azure Key Vault. For fleets we default to External Secrets. Rotation happens in one place, audit lives in the secret manager, and a leaked repository leaks nothing.

Promotion That Survives an Audit

Modeling environments as long-lived Git branches feels natural and ages terribly: merge conflicts in generated YAML, cherry-pick drift, and no crisp answer to what is running in staging right now. Model environments as directories instead — a shared base with thin per-environment overlays — and make promotion a pull request that advances an immutable artifact reference from one overlay to the next. Tools like Kargo formalize the pipeline when you need stage gates and provenance tracking, but the discipline matters more than the tool.

The checklist we hold ourselves to:

1. CI builds once and pushes an immutable image digest; nothing is ever rebuilt per environment. 2. A bot opens the promotion pull request with the rendered manifest diff attached for review. 3. Policy checks — Kyverno or OPA evaluated in CI — gate the merge, not a human eyeballing YAML. 4. Production syncs happen inside defined windows, with prune verified against a dry run first. 5. Rollback is a Git revert. If any recovery step requires kubectl apply from a laptop, the model is broken.

The payoff is operational and regulatory at once. When every production change is a reviewed, signed commit with a visible diff, the change-management evidence that SOC 2 and ISO 27001 auditors ask for falls out of the daily workflow instead of being reconstructed every quarter, and mean time to recovery shrinks to the length of a revert. Teams that invest in repository structure and promotion discipline early ship more frequently with fewer release freezes — the controller was never the hard part.

TAGS
GitOpsArgo CDKubernetesFluxContinuous Delivery

Need help with
this topic
?

Our team specializes in the technologies and strategies discussed in this article. Let's talk about how we can help your business.

Get in Touch