I am struggling with the folder structure for our GitOps repo. Should we have one repository per environment (dev, staging, prod), or one repository with branches for each environment? Some people suggest a "Mono-repo" approach with directories for each cluster. We are using Kustomize for overlays, and I want to make sure we don't end up with "Configuration Drift" between staging and production due to a messy Git structure. What is the most scalable pattern for a growing team?
3 answers
The industry consensus for GitOps is to avoid environment-based branches (like a 'prod' branch). Branching often leads to long-lived drifts that are hard to merge. Instead, use a single "Mono-repo" with a directory-based structure and Kustomize overlays. You have a base/ directory for common resources and overlays/dev/, overlays/prod/ for environment-specific changes like replica counts or ingress hosts. This ensures that every environment inherits from the same base code. To promote a change, you update the image tag in the 'staging' overlay, test it, and then move that same tag to 'prod'. This provides a clear, linear path for code promotion that is easy to audit.
How do you handle "cross-cutting" concerns like global IAM roles or networking policies that need to be identical across all your environment directories?
One repo for infra and one for apps is the way to go. It separates the concerns of the platform team from the application developers, which is vital for scaling.
Exactly, Cynthia. Separating the "Plumbing" (Cluster config) from the "Apps" helps prevent a developer from accidentally breaking the cluster's core networking while trying to update a CSS file.
Robert, we handle that by using a "Common" overlay. We treat the global policies as their own 'base' component that every environment-specific overlay must include. Using Kustomize 'components' allows us to mix and match these global policies. For instance, our 'security-hardening' component is applied to both staging and prod, but omitted in dev to give developers more freedom. This keeps the folder structure clean and ensures that when we update a global policy, it propagates through the GitOps pipeline to all environments simultaneously after a single commit.