DevOps ArgoCDGitOps

GitOps with ArgoCD: The Complete DevOps Automation Guide for 2025

Implement GitOps with ArgoCD on Kubernetes — ApplicationSets, multi-cluster deployments, progressive delivery with Argo Rollouts, and secrets management.

R

Lead DevOps Architect, KubeAce

11 min read

GitOps transforms infrastructure management from an imperative, error-prone process into a declarative, auditable one. ArgoCD is the de facto GitOps engine for Kubernetes — and with the right architecture, it can manage hundreds of applications across dozens of clusters with zero toil.

This guide covers what we’ve learned building ArgoCD platforms for engineering teams at scale.

Why GitOps? The Business Case

Before diving into ArgoCD specifics, it’s worth being precise about what GitOps delivers:

  1. Audit trail: Every change to production is a Git commit with an author, timestamp, and message
  2. Rollback: Revert any deployment to any previous state in seconds — not minutes or hours
  3. Drift detection: ArgoCD continuously compares Git state to cluster state and alerts on divergence
  4. Self-service: Developers can deploy by merging a PR — no Kubernetes access required
  5. Compliance: SOC 2 and ISO 27001 auditors love GitOps. Every production change is documented.

In our experience, teams adopting GitOps reduce deployment-related incidents by 60-80% within the first quarter.

ArgoCD Architecture for Scale

Core Components

┌─────────────────────────────────────────┐
│              ArgoCD Namespace            │
│                                         │
│  ┌──────────────┐  ┌──────────────────┐ │
│  │  API Server   │  │   Repo Server    │ │
│  │  (WebUI/CLI) │  │  (Git + Helm)    │ │
│  └──────────────┘  └──────────────────┘ │
│  ┌──────────────┐  ┌──────────────────┐ │
│  │ App Controller│  │   Redis (Cache)  │ │
│  │ (Sync Engine) │  │                  │ │
│  └──────────────┘  └──────────────────┘ │
└─────────────────────────────────────────┘

For production, always run ArgoCD with HA configuration:

  • API server: 2+ replicas
  • Repo server: 2+ replicas (CPU-intensive — Helm rendering)
  • Application Controller: 1 replica (stateful, uses sharding for multi-cluster)

Repository Structure

The “app of apps” or “ApplicationSet” pattern is how you manage many applications:

gitops-repo/
├── apps/
│   ├── base/              # Shared base configs
│   └── overlays/
│       ├── staging/
│       └── production/
├── infrastructure/
│   ├── cert-manager/
│   ├── ingress-nginx/
│   └── monitoring/
└── argocd/
    ├── projects.yaml
    └── applicationsets/
        ├── apps.yaml
        └── infrastructure.yaml

ApplicationSets: Managing Many Apps at Once

ApplicationSets are ArgoCD’s superpower. Instead of creating 50 Application resources manually, you define a generator:

# argocd/applicationsets/apps.yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: microservices
  namespace: argocd
spec:
  generators:
  - git:
      repoURL: https://github.com/your-org/gitops-repo
      revision: HEAD
      directories:
      - path: "apps/overlays/production/*"
  template:
    metadata:
      name: '{{path.basename}}'
    spec:
      project: production
      source:
        repoURL: https://github.com/your-org/gitops-repo
        targetRevision: HEAD
        path: '{{path}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{path.basename}}'
      syncPolicy:
        automated:
          prune: true        # Delete resources removed from Git
          selfHeal: true     # Revert manual changes
        syncOptions:
        - CreateNamespace=true
        - PrunePropagationPolicy=foreground

With this single ApplicationSet, every directory under apps/overlays/production/ becomes an ArgoCD Application automatically.

Multi-Cluster Management

ArgoCD can manage applications across multiple clusters from a single control plane:

# Register a remote cluster
argocd cluster add production-eks \
  --name production-eks \
  --kubeconfig ~/.kube/production

# Use in ApplicationSet
spec:
  generators:
  - matrix:
      generators:
      - clusters:
          selector:
            matchLabels:
              environment: production
      - git:
          repoURL: https://github.com/your-org/gitops-repo
          directories:
          - path: "apps/*"

This generates one Application per service per cluster — fully automated.

Progressive Delivery with Argo Rollouts

Standard Kubernetes Deployments are all-or-nothing. Argo Rollouts enables canary and blue-green strategies:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: api-server
spec:
  replicas: 10
  strategy:
    canary:
      steps:
      - setWeight: 10      # Send 10% of traffic to canary
      - pause: {duration: 5m}
      - setWeight: 30
      - pause: {duration: 5m}
      - analysis:           # Run automated analysis before proceeding
          templates:
          - templateName: success-rate
      - setWeight: 100
  selector:
    matchLabels:
      app: api-server

Combined with Prometheus metrics analysis:

apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  metrics:
  - name: success-rate
    interval: 2m
    successCondition: result[0] >= 0.95
    failureLimit: 3
    provider:
      prometheus:
        address: http://prometheus.monitoring.svc.cluster.local:9090
        query: |
          sum(rate(http_requests_total{job="api-server",status=~"2.."}[5m])) /
          sum(rate(http_requests_total{job="api-server"}[5m]))

If the success rate drops below 95% during rollout, ArgoCD automatically rolls back. Zero manual intervention.

Secrets Management in GitOps

The classic GitOps problem: how do you manage secrets without committing them to Git?

Option 1: Sealed Secrets

# Encrypt a secret with the cluster's public key
kubectl create secret generic my-secret \
  --from-literal=password=supersecret \
  --dry-run=client -o yaml | \
  kubeseal --format yaml > sealed-secret.yaml

# Safe to commit to Git — only the cluster can decrypt it
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: database-credentials
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets-manager
    kind: ClusterSecretStore
  target:
    name: database-credentials
  data:
  - secretKey: password
    remoteRef:
      key: production/database
      property: password

ESO pulls secrets from AWS Secrets Manager, GCP Secret Manager, or Vault — and syncs them as Kubernetes Secrets. No secrets in Git, ever.

CI + GitOps Integration

CI (testing, building) and GitOps (deploying) are complementary, not competing:

# GitHub Actions workflow: build + update GitOps repo
name: Build and Deploy
on:
  push:
    branches: [main]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Build and push Docker image
      run: |
        IMAGE_TAG=${{ github.sha }}
        docker build -t ghcr.io/your-org/api:$IMAGE_TAG .
        docker push ghcr.io/your-org/api:$IMAGE_TAG

    - name: Update GitOps repo
      run: |
        git clone https://github.com/your-org/gitops-repo
        cd gitops-repo
        # Update image tag in Kustomization
        kustomize edit set image api=ghcr.io/your-org/api:${{ github.sha }}
        git commit -am "ci: update api image to ${{ github.sha }}"
        git push

ArgoCD detects the commit and syncs automatically. The deployment is fully automated, fully auditable.

What We Typically Find

When we audit engineering teams’ current deployment processes, we consistently find:

  • Manual kubectl apply to production (no audit trail, no rollback)
  • Secrets in ConfigMaps or .env files in Git
  • No drift detection — production drifts from Git silently
  • No canary/blue-green — all deploys are big-bang

GitOps with ArgoCD solves all of these. Implementation takes 2-4 weeks depending on existing complexity.

If you’d like KubeAce to design and implement a GitOps platform for your team, schedule a consultation. We can have you from zero to full ArgoCD-managed GitOps in under a month.