GitOps is the practice of using Git as the single source of truth for declarative infrastructure and application configuration. Instead of running kubectl apply from laptops or CI/CD scripts, you commit your desired state to Git, and a GitOps operator (ArgoCD, Flux) continuously reconciles the cluster state to match what's in Git. If someone manually changes something in the cluster, the operator reverts it. If you want to roll back a deployment, you revert a Git commit.
ArgoCD has emerged as the dominant GitOps tool, used by over 10,000 organizations including Intuit, Red Hat, and Tesla. It provides a beautiful web UI, application health visualization, RBAC, SSO integration, and a declarative application model that scales from a single cluster to hundreds. This guide covers everything you need to deploy ArgoCD in production and manage real workloads.
Installing ArgoCD the Production Way
The quick-start installation (kubectl apply -n argocd -f https://raw.githubusercontent.com/.../install.yaml) works for testing but lacks HA, proper resource limits, and security hardening. For production, use the HA manifest or Helm chart:
# Production ArgoCD installation with Helm
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
helm install argocd argo/argo-cd --namespace argocd --create-namespace --set server.replicas=2 --set controller.replicas=2 --set repoServer.replicas=2 --set redis.enabled=true --set redis-ha.enabled=true --set server.ingress.enabled=true --set server.ingress.hosts[0]=argocd.internal.yourcompany.com --set server.ingress.tls[0].secretName=argocd-tls --set server.ingress.tls[0].hosts[0]=argocd.internal.yourcompany.com --set configs.cm."admin.enabled"=false --set configs.cm."dex.config"="$(cat dex-config.yaml)" --set server.resources.requests.cpu=250m --set server.resources.requests.memory=256Mi --set server.resources.limits.cpu=500m --set server.resources.limits.memory=512Mi --values argocd-values.yaml
The App-of-Apps Pattern
Managing individual ArgoCD Application resources quickly becomes unwieldy when you have dozens of services. The app-of-apps pattern solves this: you create a single "root" Application that points to a Git directory containing other Application manifests. ArgoCD recursively syncs all of them.
# apps/root-app.yaml — The root application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root
namespace: argocd
spec:
project: default
source:
repoURL: git@gitlab.com:yourorg/infrastructure.git
targetRevision: main
path: argocd/apps # Directory containing all Application manifests
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
---
# argocd/apps/backend-api.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: backend-api
namespace: argocd
labels:
team: backend
env: production
spec:
project: default
source:
repoURL: git@gitlab.com:yourorg/infrastructure.git
targetRevision: main
path: kubernetes/backend-api
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
Secrets Management in GitOps
The biggest challenge in GitOps is secrets. You can't commit plaintext secrets to Git (obviously), but your applications need database passwords, API keys, and TLS certificates. Several solutions exist:
Sealed Secrets (Bitnami): Encrypt secrets with a cluster-specific public key. The encrypted SealedSecret resource is safe to commit to Git. The Sealed Secrets controller in the cluster decrypts it into a regular Kubernetes Secret. Simple and effective for most teams.
External Secrets Operator: Syncs secrets from external secret managers (AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager, Azure Key Vault) into Kubernetes Secrets. The Git repo contains only the reference to the secret, not the secret itself. Best for organizations that already use an external secret manager.
SOPS (Mozilla): Encrypts values within YAML files using age, PGP, or cloud KMS. The encrypted file can be committed to Git, and ArgoCD decrypts it during sync using the KSOPS plugin. Good balance of security and developer experience.
# Using External Secrets Operator with AWS Secrets Manager
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: database-credentials
namespace: production
spec:
refreshInterval: 1h
secretStoreRef:
kind: ClusterSecretStore
name: aws-secrets-manager
target:
name: database-credentials
creationPolicy: Owner
data:
- secretKey: DB_HOST
remoteRef:
key: production/database
property: host
- secretKey: DB_PASSWORD
remoteRef:
key: production/database
property: password
Progressive Rollouts with Argo Rollouts
Standard Kubernetes Deployments use a rolling update strategy that replaces pods one by one. This works but provides no control over traffic distribution and no automatic rollback based on metrics. Argo Rollouts extends Kubernetes with canary deployments and blue-green deployments that integrate with your observability stack.
# Canary rollout with automated analysis
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: backend-api
namespace: production
spec:
replicas: 10
strategy:
canary:
steps:
- setWeight: 5 # Send 5% of traffic to new version
- pause: { duration: 5m } # Wait 5 minutes
- analysis: # Run automated analysis
templates:
- templateName: success-rate
args:
- name: service-name
value: backend-api
- setWeight: 25 # If analysis passes, increase to 25%
- pause: { duration: 10m }
- analysis:
templates:
- templateName: success-rate
- setWeight: 50
- pause: { duration: 10m }
- setWeight: 100 # Full rollout
canaryService: backend-api-canary
stableService: backend-api-stable
trafficRouting:
nginx:
stableIngress: backend-api-ingress
---
# Automated analysis template — checks error rate during canary
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
args:
- name: service-name
metrics:
- name: success-rate
interval: 60s
successCondition: result[0] >= 0.99
failureLimit: 3
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(http_requests_total{service="{{args.service-name}}",
status=~"2.."}[5m]))
/
sum(rate(http_requests_total{service="{{args.service-name}}"}[5m]))
Multi-Cluster Management
ArgoCD can manage multiple Kubernetes clusters from a single control plane. Register additional clusters and use ApplicationSets to automatically generate Applications for each cluster:
# Register a remote cluster
argocd cluster add production-us-east --name prod-us-east
argocd cluster add production-eu-west --name prod-eu-west
# ApplicationSet — deploy to all clusters automatically
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: backend-api-all-clusters
namespace: argocd
spec:
generators:
- clusters:
selector:
matchLabels:
env: production
template:
metadata:
name: 'backend-api-{{name}}'
spec:
project: default
source:
repoURL: git@gitlab.com:yourorg/infrastructure.git
targetRevision: main
path: kubernetes/backend-api
destination:
server: '{{server}}'
namespace: production
Operational Best Practices
Separate app config from app source code. Keep Kubernetes manifests in a dedicated infrastructure repository, not alongside application code. This prevents CI pipelines from triggering deployment pipeline runs and allows infrastructure changes to be reviewed independently.
Use Kustomize overlays for environment promotion. Base manifests define the application, overlays customize per environment (dev/staging/production). Promoting from staging to production means updating the image tag in the production overlay — a one-line Git commit.
Enable notifications. ArgoCD can send Slack/Teams/email notifications on sync failures, health degradation, and successful deployments. Configure these from day one — silent failures are the worst kind.
Set sync windows. Prevent automated syncs during business-critical hours. ArgoCD sync windows let you define maintenance windows when automated deployments are allowed.
ZeonEdge helps organizations implement GitOps workflows with ArgoCD, including multi-cluster management, progressive rollouts, and secrets management. Talk to our DevOps team.
Marcus Rodriguez
Lead DevOps Engineer specializing in CI/CD pipelines, container orchestration, and infrastructure automation.