, ,

Deploying Applications on VKS with GitOps: Argo CD, Flux and Helm (VKS Series, Part 13)

Application delivery on VKS is just Kubernetes; Argo CD, Flux and Helm work unchanged. Here is the honest boundary, and the four VKS-specific wiring points that trip people up.

Deploying Apps with GitOps: Argo CD, Flux, Helm
VKS Series · Part 13 of 17

TL;DR · Key Takeaways

  • Application delivery on VKS is ordinary Kubernetes. Argo CD, Flux and Helm work exactly as on any conformant cluster, because that is what a VKS cluster is.
  • What is VKS-specific is the wiring: private registry access, an ingress path for the GitOps server, Supervisor and cluster RBAC, and storage classes for stateful pieces.
  • GitOps fits VKS well: clusters are declarative from the infrastructure up, so making the apps declarative too gives one consistent model end to end.
  • Be honest about the boundary, VKS gives you the cluster; the delivery platform on top is yours to choose and run, just like anywhere else.
Who this is for: teams bringing an existing GitOps practice onto VKS, or standing one up.  Prerequisites: a running cluster, plus Parts 7, 8 and 10 (ingress, storage, RBAC).

Here is the honest framing up front: deploying applications on VKS is not special. A VKS cluster is a conformant Kubernetes cluster, so Argo CD, Flux, Helm and everything else in the cloud-native toolbox behave the way they always do. That is a feature, not a disappointment, your existing skills and pipelines transfer directly. What is worth covering is the handful of VKS-specific integration points that trip people up when they bring their delivery stack across, all of which we have already met in this series.

GitOps on VKS: declarative all the way down

GitOps is a natural fit for VKS because the cluster itself is already declarative, from the Cluster API manifest up. Adding Argo CD or Flux extends that same model to your applications: Git is the source of truth, a controller reconciles the cluster to match, and drift is corrected automatically. You install Argo CD or Flux into the cluster like any workload and point it at your repositories, nothing about the install is VKS-specific. The payoff is consistency: when both your cluster definition and your application definition live in Git and are reconciled continuously, you have one operating model for the whole stack. On a multi-tenant VKS platform that matters even more, because you want every team shipping the same way rather than each inventing its own deployment ritual.

The reconcile loop Git repodesired state Argo CD / Fluxdetects + applies changes VKS clusterlive state matches Git continuous drift correction
Git holds desired state; the controller reconciles the VKS cluster to it and keeps correcting drift, the same loop you run anywhere.

The VKS-specific wiring

Four integration points are where VKS asks for attention, and getting any one wrong produces a failure that looks like a GitOps problem but is really plumbing:

ConcernWhat to wire upFailure if you skip it
Private registryImage pull secrets + allowed registries (Part 10)ImagePullBackOff
Ingress for the GitOps serverNSX/Avi ingress or LoadBalancer (Part 7)Argo CD UI/API unreachable
RBAC alignmentMap service accounts to cluster RBAC (Part 10)Controller cannot create resources
Stateful componentsA StorageClass backed by an SPBM policy (Part 8)PVCs stay Pending

Helm is the common packaging layer underneath all of this and works on VKS unchanged, charts install, values override, releases roll back, exactly as upstream. The only VKS-flavoured considerations are the same four above: point chart image references at your private registry, set the right StorageClass in values for stateful charts, and expose services through your chosen ingress. Whether you drive Helm directly, through Argo CD, or through Flux is a team preference, not a VKS constraint.


Don’t relearn Kubernetes delivery: the real advantage on VKS is consistency, not novelty. Spend your effort on the four wiring points and on standardising one delivery pattern across teams, not on treating VKS application delivery as a new discipline. It is your existing GitOps practice on a vSphere-integrated cluster.

Repo structure: app-of-apps and per-team boundaries

How you lay out the Git repositories decides whether GitOps scales or turns into a tangle, and it is worth getting right before the second team arrives. The pattern that holds up is a clear separation between platform and application config: a platform repo that bootstraps clusters and installs shared add-ons, and per-team or per-app repos that hold the workloads. Argo CD’s app-of-apps pattern (or Flux’s equivalent) lets a single root application install and manage everything else, so a new cluster bootstraps itself from one entry point rather than a human applying twelve manifests in the right order. Per-team repos give each team ownership of their own deployments while the platform repo keeps the guardrails, which mirrors the RBAC and namespace tenancy model from the security part.

The anti-pattern is one giant repo that everyone commits to, where a typo in a shared file breaks every team and access control is all or nothing. Split by ownership boundary, give the GitOps controller scoped access to each, and let the structure of the repos reflect the structure of who is responsible for what. That alignment is what lets you onboard a tenth team without the ninth noticing.

Secrets in GitOps without leaking them

GitOps wants everything in Git, and the obvious problem is that you cannot put plaintext secrets there. This trips up almost every team that adopts GitOps, and the answer is not to make an exception for secrets but to store them safely. The two common approaches are sealed secrets, where a controller in the cluster holds a private key and only it can decrypt the encrypted secret you commit, and external secrets, where Git holds a reference and the actual value lives in a real secrets manager that the cluster reads at runtime. Either keeps Git as the source of truth for what exists while keeping the sensitive value out of the repo. On VKS this is the same as anywhere else, which is the point: your existing secrets practice transfers, and you should not invent a VKS-specific one.

Pick one approach and standardise it, because a platform where each team handles secrets differently is one where someone eventually commits a plaintext credential and it ends up in the Git history forever. Decide the pattern in the platform repo, document it, and make it the paved road so nobody has a reason to improvise.

Progressive delivery and the rollback that GitOps gives you

The quiet superpower of GitOps is that rollback is just reverting a commit. Because the cluster reconciles to whatever Git says, undoing a bad deploy is a git revert and a wait, not a frantic manual rebuild, and the audit trail of what changed and when is the commit history for free. That alone is worth the setup cost. On top of it, progressive delivery tools, Argo Rollouts or Flux’s Flagger, let you ship changes as canaries or blue-green cuts, shifting a fraction of traffic to the new version, watching the metrics, and promoting or aborting automatically based on whether the golden signals hold. Combined with the centralized analytics from an Avi or Prometheus setup, that turns a risky deploy into a measured one.

This is where the consistency argument pays off in production rather than just tidiness. A platform where every team ships through the same GitOps pipeline, with the same canary mechanism and the same revert-to-roll-back behaviour, is a platform where a bad change is contained and reversible by default. The work is in setting up that paved road once, in the platform repo and the cluster bootstrap, so that delivery-ready is the state every new cluster arrives in rather than something each team rebuilds by hand. Get that bootstrap right and the four wiring points from earlier are configured before any developer touches the cluster.

Repo topology: platform versus team

How you lay out the Git repositories decides whether GitOps scales or turns into a tangle, and it is worth a picture because the boundary mirrors your tenancy model. A platform repo bootstraps clusters and installs shared add-ons; per-team repos hold the workloads. A root application installs and manages everything else, so a new cluster bootstraps from one entry point rather than a human applying manifests in the right order.

Split repos by ownership boundary Platform reporoot app-of-appscluster bootstrapshared add-ons + guardrailsowned by platform team Team A repotheir workloads, scoped access Team B repoindependent, own RBAC Anti-patternone giant repo everyonecommits to: a typo breaksevery team; access all-or-nothing
Repo structure should mirror who owns what, so onboarding a tenth team does not disturb the ninth.

Secrets that do not leak into Git

GitOps wants everything in Git, which collides with the obvious rule that plaintext secrets must never go there. The answer is not an exception but a safe mechanism: sealed secrets, where only an in-cluster key can decrypt what you commit, or external secrets, where Git holds a reference and the value lives in a real secrets manager. Pick one, standardise it in the platform repo, and make it the paved road so nobody improvises and commits a credential that lives in the history forever.

In practice

The day a team adopts GitOps, someone asks where the database password goes. If you have not already chosen sealed secrets or external secrets and documented it, the honest answer becomes “well, just this once in a plain manifest,” and that plaintext credential is now in the Git history permanently. Decide the secrets pattern before the first workload, not after the first leak.

Rollback is a git revert

The quiet superpower of GitOps is that undoing a bad deploy is reverting a commit. Because the cluster reconciles to whatever Git says, rollback is a git revert and a wait, and the audit trail of what changed is the commit history for free. The loop is worth seeing because it is the same loop that ships changes, run in reverse.

Rollback without a rebuild bad deploycommit N breaks prod git revert None command, audited controller reconcilescluster matches Git again recoveredknown-good Progressive delivery (canary, blue-green) shifts a fraction of traffic first, so most bad changes never reach all users.
Reverting a commit is the rollback. The history is the audit trail. No frantic manual rebuild.

Progressive delivery on top

Above plain rollback, progressive delivery tools ship changes as canaries or blue-green cuts, shifting a fraction of traffic to the new version, watching the golden signals, and promoting or aborting automatically. Combined with the analytics from an Avi or Prometheus setup, that turns a risky deploy into a measured one where most bad changes never reach all users in the first place. The work is in setting up that paved road once, in the platform repo and the cluster bootstrap, so delivery-ready is the state every new cluster arrives in.

Worked example

A bad config change shipped to a service at 2am. Because the team ran GitOps, the on-call engineer did not debug the live cluster; they reverted the offending commit and the controller reconciled the service back to its previous state within a couple of minutes, with the whole event recorded in the Git history for the morning review. The same change on a hand-deployed cluster would have meant reconstructing the previous config under pressure. Revert and wait beat rebuild and hope, every time.

Drift detection as a guardrail

A benefit of GitOps that goes underused is drift detection: because the controller knows the desired state, it also knows when the live cluster no longer matches it, which means it can tell you the moment someone makes a manual change out of band. That is a genuine security and stability guardrail, because the manual kubectl edit at 3am that fixes an incident and is never written back to Git is exactly the change that gets lost on the next reconcile or, worse, persists silently and diverges your environments. Run the controller in a mode that surfaces drift, decide deliberately whether it auto-corrects or alerts a human, and treat any detected drift as a signal that either Git needs updating or someone bypassed the process. Either way you find out, rather than discovering months later that production and the repository quietly stopped agreeing and nobody can say which is correct.

What I’d Do

I treat VKS application delivery as a solved problem with a short setup checklist, not a new platform to design. I pick one GitOps tool, Argo CD or Flux, and standardise it across every team so there is one way to ship. I wire the four VKS-specific points once, registry access, ingress for the GitOps server, RBAC for its service accounts, and storage for stateful add-ons, and bake them into a cluster bootstrap so every new cluster arrives delivery-ready. Then I get out of the developers’ way, because the whole point is that their existing skills work unchanged. Resist the urge to make this special. Is your VKS application delivery one standard pattern your platform bootstraps automatically, or does every team wire up Argo CD slightly differently and rediscover the same four gotchas?

References

VKS Series · Part 13 of 17
« Prev: Part 12  |  VKS Complete Guide  |  Next: Part 14 »

About The Author


Discover more from Journal of Intelligent Infrastructure

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *

Architect’s Toolkit

About the Author

Dr. Pranay Jha is a Cloud and AI Consultant with 18+ years of experience in hybrid cloud, virtualization, and enterprise infrastructure transformation. He specializes in VMware technologies, multi-cloud strategy, and Generative AI solutions. He holds a PhD in Computer Applications with research focused on Cloud and AI, has published multiple research papers, and has been a VMware vExpert since 2016 and a VMUG Community Leader.

Discover more from Journal of Intelligent Infrastructure

Subscribe now to keep reading and get access to the full archive.

Continue reading