Why GitOps changes enterprise operations
The traditional push-based model (CI pipeline applies changes directly to the cluster via kubectl) has fundamental auditability and consistency problems. What version is running in production right now? Who applied the last change and when? Can I reproduce the exact cluster state from three weeks ago? With GitOps, all these questions are answered by the Git history.
The less talked-about benefit: GitOps makes manual production changes non-persistent by design. ArgoCD detects any deviation from the declared state in Git and automatically reverts it. This eliminates the practice of applying hotfixes directly to the cluster without documentation — one of the most frequent sources of hard-to-diagnose incidents.
ArgoCD: base configuration for production
ArgoCD introduces the Application as a Kubernetes resource. Each Application defines which Git repository to watch, which path contains the manifests, and which cluster/namespace to apply them to.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: api-production
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/company/infra-gitops.git
targetRevision: main
path: apps/api/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true # removes resources no longer defined in Git
selfHeal: true # reverts manual cluster changes
syncOptions:
- CreateNamespace=trueselfHeal: true enables automatic reconciliation against drift. prune: true removes cluster resources that are no longer defined in Git. For high-criticality changes, consider disabling automated sync and requiring manual sync with approval — the balance between automation and control depends on the service SLA.
App of Apps: architecture for multiple teams
The App of Apps pattern allows a root Application to manage all other applications as code. Instead of manually creating each Application through the UI or kubectl, you define a root app that watches a directory containing all other application manifests.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-apps
namespace: argocd
spec:
source:
repoURL: https://github.com/company/infra-gitops.git
path: apps/
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: trueWith this architecture, each team manages their own applications through PRs to the central infrastructure repository. No developer needs direct access to the production cluster — ArgoCD is the only actor that applies changes.
Secrets Management with GitOps: the real challenge
Secrets management is the primary barrier to GitOps adoption in enterprises. You can't commit credentials to Git, even in private repositories. The two production-grade solutions we use in enterprise projects:
Sealed Secrets (Bitnami): Encrypts secrets with the cluster's public key. The encrypted SealedSecret can safely live in Git — only the cluster can decrypt it with its private key. This is the simplest solution when all secrets are cluster-specific.
# Create and seal a Secret in one command
kubectl create secret generic db-credentials \
--from-literal=password=mysecretpassword \
--dry-run=client -o yaml | \
kubeseal --format yaml > sealed-db-credentials.yaml
# The sealed file can be safely committed to GitExternal Secrets Operator: Syncs secrets from AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager, or Azure Key Vault directly to Kubernetes Secrets. The best choice for enterprises that already have a centralized secrets management solution or need to rotate credentials without redeploying.
Enterprise RBAC with ArgoCD Projects
In an organization with multiple teams sharing the same cluster, access control in ArgoCD is critical. AppProjects let you restrict which repositories each team can use, which clusters they can deploy to, and which namespaces they can manage.
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: team-payments
namespace: argocd
spec:
description: Payments team project
sourceRepos:
- 'https://github.com/company/payments-service.git'
destinations:
- namespace: payments-*
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: ''
kind: NamespaceThe payments team can only deploy from their repository, only to namespaces prefixed with payments-. Any attempt to access other namespaces or clusters fails at ArgoCD validation, without requiring manual intervention.
CI Integration: the pull vs. push distinction
With GitOps, the CI pipeline only updates the infrastructure repository (new image tag, new configuration). ArgoCD detects the change and applies the new state to the cluster. CI never communicates directly with the cluster.
# GitLab CI — stage that updates the image tag in the infra repo
update-image-tag:
stage: deploy
script:
- git clone https://oauth2:${GITOPS_TOKEN}@github.com/company/infra-gitops.git
- cd infra-gitops
- |
sed -i "s|image: company/api:.*|image: company/api:${CI_COMMIT_SHORT_SHA}|g" \
apps/api/production/deployment.yaml
- git config user.email "ci@company.com"
- git config user.name "GitLab CI"
- git commit -am "ci: update api to ${CI_COMMIT_SHORT_SHA}"
- git push origin main
only:
- mainThis separation is fundamental for auditing and compliance. Every production change has a Git commit with an identified author. Rollback is a git revert. ArgoCD's reconciliation guarantees the cluster state always converges to the state declared in Git.
Rollback in 30 Seconds
One of the most concrete advantages of GitOps is instant rollback. The desired state is the Git commit — rolling back means selecting a previous revision in ArgoCD or running git revert in the repository. No complex kubectl commands, no configuration reconstruction.
In production, an ArgoCD rollback takes as long as reconciliation (typically 30-90 seconds). Compared to the manual process of identifying the previous image, editing the deployment, applying and verifying, the MTTR difference can be minutes to hours.
Frequently Asked Questions
Is GitOps only for Kubernetes?
ArgoCD or FluxCD for an enterprise?
How do I handle feature flags and application configuration in GitOps?
What happens if someone does a manual kubectl edit in production?
How long does it take to implement GitOps in a company using manual deploys?
Is your team transitioning from manual kubectl deploys to a professional GitOps workflow? We implement ArgoCD in production with the right practices from the start.
Talk to our team