Basic ArgoCD setup works fine when there are only a few applications. The pressure shows up later: dozens of services, multiple environments, shared platform dependencies, and production changes that need a clear promotion trail. These are the patterns I would put in place before the GitOps repo becomes hard to reason about.
Repository Strategy
A practical approach:
- app source code in service repos
- deployment manifests in environment repos
- platform/base components in shared repo
This separation keeps deployment governance independent from application release cadence.
App of Apps Pattern
Use one root application per environment that manages child apps.
Benefits:
- consistent environment bootstrapping
- centralized visibility
- easier disaster recovery recreation
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: prod-root
namespace: argocd
spec:
project: production
source:
repoURL: https://github.com/company/platform-gitops
path: environments/prod/apps
targetRevision: main
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
Promotion Flow Between Environments
Use explicit promotion commits instead of direct production edits:
- Merge to
dev - Validate automated tests and smoke checks
- Promote same artifact digest to
staging - Promote approved digest to
prod
Key rule: promote immutable image digests, not mutable tags.
Sync Waves and Hooks
Complex systems need ordered deployment:
- CRDs first
- platform dependencies second
- application workloads last
Use sync waves:
metadata:
annotations:
argocd.argoproj.io/sync-wave: "10"
Use pre-sync and post-sync hooks for database migrations and smoke tests.
Drift and Policy Controls
- enable
selfHealcarefully in production - block manual cluster edits for managed resources
- use policy checks for critical manifests
- alert on repeated drift
Progressive Delivery with Argo Rollouts
For high-risk services:
- canary with metrics-based analysis
- automatic rollback on SLO degradation
- staged traffic increase
This combines GitOps consistency with runtime risk control.
Multi-Tenant ArgoCD Setup
- create ArgoCD Projects per team or domain
- restrict source repos and destination namespaces
- enforce RBAC and SSO groups
This avoids cross-team blast radius in shared clusters.
Anti-Patterns
- one giant repo with no environment boundaries
- direct production commits bypassing promotion flow
- mutable image tags in production
- unmanaged dependencies without sync ordering
Production Baseline
- App of Apps per environment
- digest-based promotion flow
- sync waves for dependencies
- policy + RBAC boundaries
- progressive delivery for critical services
The baseline is intentionally boring. That is the point: GitOps should make production change reviewable and repeatable, not turn the deployment repo into a second application nobody wants to own.