Bilal Ahmad

~Engineers solve problems, I solve engineer's problems 🤘

GitOps with Argo CD vs Flux

A practical comparison of the two leading GitOps tools for Kubernetes deployments, focusing on reconciliation models, drift detection, multi-cluster strategies, and secrets handling.

What is GitOps?

GitOps is a methodology where Git serves as the single source of truth for declarative infrastructure and applications. Changes are made through Git commits, and an automated process ensures the actual state matches the desired state.

Argo CD vs Flux: Quick Comparison

Feature Argo CD Flux
Architecture Pull-based, agent in cluster Pull-based, operator in cluster
UI Rich web interface CLI-focused, basic UI
Multi-cluster Native support Native support
Helm Support Excellent Excellent
Kustomize Native Native
Learning Curve Moderate Steep
Resource Usage Higher Lower

Reconciliation Models

Argo CD

# Argo CD Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
spec:
  project: default
  source:
    repoURL: https://github.com/myorg/myapp
    targetRevision: HEAD
    path: k8s
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true

Flux

# Flux GitRepository
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: my-app
  namespace: flux-system
spec:
  interval: 1m
  url: https://github.com/myorg/myapp
  ref:
    branch: main
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: my-app
  namespace: flux-system
spec:
  interval: 5m
  sourceRef:
    kind: GitRepository
    name: my-app
  path: "./k8s"
  prune: true
  validation: client

Drift Detection

Argo CD

Flux

Multi-cluster Strategies

Argo CD

# Argo CD ApplicationSet for multi-cluster
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: my-app-multicluster
spec:
  generators:
  - clusters:
      selector:
        matchLabels:
          environment: production
  template:
    metadata:
      name: '-my-app'
    spec:
      project: default
      source:
        repoURL: https://github.com/myorg/myapp
        targetRevision: HEAD
        path: k8s
      destination:
        server: ''
        namespace: production

Flux

Secrets Handling

Argo CD

# Argo CD with Sealed Secrets
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app-with-secrets
spec:
  source:
    repoURL: https://github.com/myorg/myapp
    path: k8s
  syncPolicy:
    syncOptions:
    - CreateNamespace=true
  sources:
  - repoURL: https://github.com/myorg/secrets
    path: sealed-secrets
    targetRevision: main

Flux

# Flux with External Secrets
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-backend
  namespace: flux-system
spec:
  provider:
    vault:
      server: "https://vault.example.com"
      path: "secret"
      version: "v2"
      auth:
        kubernetes:
          mountPath: "kubernetes"
          role: "flux"
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: my-app-secrets
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: my-app-secrets
    creationPolicy: Owner
  data:
  - secretKey: database-password
    remoteRef:
      key: my-app
      property: db-password

When to Choose Which?

Choose Argo CD when:

Choose Flux when:

Best Practices

For Both Tools:

Repository Structure Example:

my-gitops-repo/
├── clusters/
│   ├── production/
│   │   ├── apps/
│   │   └── infrastructure/
│   └── staging/
│       ├── apps/
│       └── infrastructure/
├── apps/
│   ├── my-app/
│   │   ├── base/
│   │   └── overlays/
│   └── another-app/
└── infrastructure/
    ├── monitoring/
    └── networking/

Migration Considerations

back