Kubernetes in Production - Part 2
Infrastructure15 min read

GitOps with ArgoCD: Declarative Kubernetes Deployments

Implementing GitOps workflows with ArgoCD for automated, auditable, and rollback-friendly deployments to Kubernetes.

KubernetesGitOpsArgoCDCI/CD

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.

yaml
# 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=true

Repository Structure

How you organize your GitOps repository matters. I use a structure that separates base manifests from environment-specific overlays using Kustomize:

text
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:

bash
# 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.