GitOps with ArgoCD: Declarative Kubernetes Deployments
Implementing GitOps workflows with ArgoCD for automated, auditable, and rollback-friendly deployments to Kubernetes.
What is GitOps?
GitOps is an operational framework that takes DevOps best practices used for application development and applies them to infrastructure automation. The core idea: Git is the single source of truth for your entire system.
- *All configuration stored in Git repositories
- *Changes made through pull requests (auditable, reviewable)
- *Automated sync between Git state and cluster state
- *Drift detection and self-healing
Why ArgoCD?
I evaluated several GitOps tools including Flux, Jenkins X, and ArgoCD. ArgoCD won for my use case because of its excellent UI, multi-cluster support, and straightforward application model.
# ArgoCD Application definition
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-manifests
targetRevision: HEAD
path: apps/my-app/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: my-app
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=trueRepository Structure
How you organize your GitOps repository matters. I use a structure that separates base manifests from environment-specific overlays using Kustomize:
k8s-manifests/
├── apps/
│ ├── my-app/
│ │ ├── base/
│ │ │ ├── deployment.yaml
│ │ │ ├── service.yaml
│ │ │ └── kustomization.yaml
│ │ └── overlays/
│ │ ├── staging/
│ │ │ ├── kustomization.yaml
│ │ │ └── replica-patch.yaml
│ │ └── production/
│ │ ├── kustomization.yaml
│ │ └── replica-patch.yaml
├── infrastructure/
│ ├── cert-manager/
│ ├── ingress-nginx/
│ └── monitoring/
└── clusters/
├── staging/
└── production/Deployment Strategies
ArgoCD supports multiple sync strategies. For production, I use automated sync with self-heal enabled, but with sync windows to prevent deployments during peak hours.
Be careful with automated pruning in production. It will delete resources that aren't in Git, which can cause outages if you're not careful about what's tracked.
Secrets Management
The one thing GitOps doesn't solve elegantly is secrets. You can't (and shouldn't) commit secrets to Git. I use Sealed Secrets to encrypt secrets that can be safely stored in Git:
# Seal a secret for GitOps
kubeseal --format=yaml \
--cert=pub-sealed-secrets.pem \
< secret.yaml > sealed-secret.yaml
# The sealed secret can be committed to Git
git add sealed-secret.yaml
git commit -m "Add database credentials (sealed)"Results
After implementing GitOps with ArgoCD, deployment confidence increased significantly. Every change is reviewed, tracked, and can be rolled back by reverting a Git commit. The cluster state always matches what's in Git.
Found this helpful?
I write about infrastructure, backend development, and DevOps. Follow along as I continue building.