ArgoCD GitOps Deployment Strategy — Git as the Single Source of Truth
GitOps is often introduced as “a way to put YAML in Git and deploy automatically.” But the real core is not automation itself. It is forcing Git to be the source of operational changes and making cluster state recoverable in a declarative way.
ArgoCD is one of the most representative tools for implementing this model on Kubernetes. But installing it does not mean GitOps is complete. What really matters is defining the operating model: what repository structure to use, how promotion works, how drift is handled, and who is allowed to change what.
Architecture overview
[Developer / Platform Team]
|
v
[Git Repository]
app config / env overlays
|
v
[Pull Request]
|
v
[Merge to Main]
|
v
[ArgoCD]
|
v
[Kubernetes Cluster]
What matters in GitOps is that people do not modify the cluster directly, and Git becomes the source of change. ArgoCD compares the desired state declared in Git with the actual cluster state, then syncs or repairs drift when they differ. That is why the core of this model is less about deployment automation itself and more about change control and recoverability.
The essence of GitOps is change control, not deployment automation
Developer change -> Git commit/PR -> merge -> ArgoCD sync -> applied to cluster
The value of this flow is not just simple automation.
- You can trace what changed and when through Git history.
- Even if someone makes a manual cluster change, you can return to the declared state.
- You can reduce how often people directly touch the cluster with
kubectl. - You can apply review and approval processes to operational changes too.
In other words, GitOps is closer to an operations change management model than just a deployment tool.
More important than installing ArgoCD: deciding what counts as truth
kubectl create namespace argocd
kubectl apply -n argocd -f \
https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Installation is not difficult, but the real design questions come after that.
- Should application code and deployment configuration live in separate repositories?
- How should environment overlays be structured?
- Who is allowed to modify which branches?
- Should deployment promotion be represented through PRs or through tags?
Because ArgoCD ultimately watches Git, the Git structure becomes the operating structure.
An Application is not just a resource, but a deployment boundary
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-configs
targetRevision: main
path: apps/my-app/overlays/prod
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
This definition declares “what to read from where, and which cluster/namespace to apply it to.” That means an Application is not just one app. It is a unit of deployment responsibility.
Good boundaries usually come from the following criteria.
- Is team ownership clear?
- Does it align naturally with rollback and approval boundaries?
- Is it a set of resources that should be deployed together?
Repository structure determines long-term operating cost
k8s-configs/
└── apps/my-app/
├── base/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
└── overlays/
├── staging/
└── prod/
This structure is widely used for a simple reason: it separates common declarations from environment-specific differences. But as operations scale, you also need to think through the following.
- Should the layout center on app folders or environment folders?
- Should shared infrastructure and app config live in the same repo?
- At which layer should variables be introduced: Helm or Kustomize?
GitOps ultimately means the repo structure shapes how people think about operating the system.
Automatic sync is powerful, but it should be enabled carefully
syncPolicy:
automated:
prune: true
selfHeal: true
These options are convenient, but their meaning is significant.
prune: Remove from the cluster any resource that was removed from Git.selfHeal: Restore manual cluster changes back to the Git-defined state.
The moment you enable this, you are effectively declaring the principle that “manual cluster changes are only temporary exceptions, and in the end Git wins.”
That principle is extremely useful in practice, but it can also conflict with manual hotfixes or emergency actions, so the team needs explicit agreement on it.
Drift recovery is one of the biggest advantages of GitOps
During operations, someone may run kubectl edit, trigger a Helm upgrade directly, or an external controller may alter state. In those cases, ArgoCD shows the difference between the desired state and the actual state and can restore it.
What makes this important is not simple convenience. It makes operational state predictable again. In GitOps, self-heal is both an automation feature and a drift-control strategy.
Updating image tags is a common promotion point in GitOps
images:
- name: my-app
newTag: "1.2.3"
- name: Update image tag
run: |
cd k8s-configs
kustomize edit set image my-app=my-app:${{ github.sha }}
git config user.email "ci@github.com"
git add . && git commit -m "ci: update image to ${{ github.sha }}"
git push
The key to this pattern is that CI does not touch the cluster directly. Instead, it changes Git state to trigger deployment. That means deployment history stays in Git, and rollbacks become more natural through git revert.
Promotion strategy must be defined clearly
In practice, teams usually face questions like these.
- How should an image validated in staging be promoted to production?
- Should the same artifact be promoted, or should each environment rebuild it?
- Should production sync automatically, or require manual approval?
If those questions do not have clear answers, GitOps remains just an automated deployment tool, while the actual operating model stays vague.
Good promotion strategies usually have these characteristics.
- The change path is visible through a Git PR.
- The difference between staging and production is traceable.
- The rollback path is simple.
In multi-environment and multi-cluster setups, Projects and permissions matter
Once you use ArgoCD seriously, you end up managing not just one app but many apps, teams, and environments. At that point, Project and RBAC become more important than individual Applications.
- Which team can deploy to which namespace or cluster?
- Which repositories are allowed to be referenced?
- Who is allowed to sync production?
GitOps does not automatically become safe just because it is declarative. It becomes much stronger when permission boundaries are clear.
GitOps has limits too
There are also cases where GitOps is not a perfect fit, or where you need to be careful.
- Situations where a very short hotfix must be applied immediately
- Cases where secret management strategy is still incomplete
- Workloads with many external dependencies, where declarative state alone is not enough for recovery
- Team cultures where people frequently need to make operational changes without a PR
In other words, adopting GitOps often requires more cultural change in operations than tool adoption alone.
Common mistakes in real environments
- Mixing code repos and deployment repos without a clear boundary
- Turning on auto-sync without a strategy for operational exceptions
- Leaving production promotion criteria ambiguous
- Treating secret management as separate from GitOps
- Continuing to operate manually with
kubectl, while Git remains only a reference
Especially in that last case, the benefits of GitOps shrink dramatically. If Git is not the source of truth, ArgoCD becomes little more than a deployment dashboard.
Closing thoughts
The value of ArgoCD is not just that it automatically applies YAML to Kubernetes. More fundamentally, it is about controlling operational changes around Git and making cluster state recoverable in a declarative way.
Well-designed GitOps does more than automate deployments. It makes operations more predictable. In the end, what matters more than how to install ArgoCD is deciding first: “What changes will our team require through Git, and what deployment flow will we standardize on?”
What Gets Hard in Production
- GitOps succeeds when Git is truly the desired-state authority and operational exceptions are minimized.
- Argo CD introduces visibility and repeatability, but it also makes drift, sync policy, and multi-environment structure explicit problems to solve.
- The hardest part is often repository design and promotion flow, not the Argo CD UI.
Architecture Decisions That Matter
- Define application boundaries, repo layout, and environment promotion strategy before onboarding many services.
- Choose automated sync, manual approval, and drift correction rules per risk level.
- Keep secrets, generated manifests, and reusable platform overlays under a coherent policy.
Practical Example
A common GitOps structure separates app intent from environment overlays:
apps/
payments/
catalog/
environments/
staging/
production/
Anti-Patterns to Avoid
- Keeping emergency manual cluster changes with no path back to Git.
- Using one repo structure that nobody can explain after the second environment is added.
- Syncing everything automatically without a risk model.
Operational Checklist
- Audit drift events and manual override frequency.
- Test promotion and rollback paths regularly.
- Monitor sync latency and failed reconciliation causes.
- Review RBAC and secret management boundaries.
Final Judgment
Argo CD works when GitOps is treated as an operational discipline, not just a deployment tool. The real system is the repo model plus reconciliation policy together.
Continue Reading
Related posts
Kubernetes Advanced Operations — HPA, Resource Management, and Pod Scheduling
This article explains Kubernetes operations not as a collection of settings but from the perspective of resource placement and resilience. It covers when and how to use requests/limits, HPA, affinity, taints, PDBs, and probes in real environments.
🚀 DevOpsKubernetes Fundamentals Design Guide
This article explains Kubernetes Pods, Deployments, and Services not as isolated object definitions but through the lens of an operating model. It covers declarative deployment, network abstraction, configuration separation, and practical adoption concerns.
📚 IT StoriesHow Containers and Kubernetes Changed the Feeling of Deployment
Deployment once felt like a tense event. Containers and Kubernetes helped turn it into something more repeatable, automated, and systematized.
📈 TrendsKubernetes v1.34: What Platform Teams Should Actually Watch
A practical reading of Kubernetes v1.34 for platform teams, focusing on the changes that most affect operations, workload design, and cluster governance.
Next Path