ArgoCDGitOpsKubernetes Aug 2024 11 min read

ArgoCD and GitOps: A Production Setup Guide

How to set up ArgoCD properly on EKS — repository structure, Application manifests, progressive delivery with Argo Rollouts, and the mistakes that will bite you if you skip them.

What GitOps actually means in practice

GitOps is not a tool — it's a principle: Git is the single source of truth for your infrastructure and application state. ArgoCD is the most mature implementation of this principle for Kubernetes. After running ArgoCD across production EKS clusters managing 30+ microservices, here's how to set it up properly and avoid the mistakes that bite you later.

Installation

# Install ArgoCD into its own namespace
kubectl create namespace argocd
kubectl apply -n argocd -f   https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# Wait for all pods to be ready
kubectl wait --for=condition=Ready pod   -l app.kubernetes.io/name=argocd-server   -n argocd --timeout=120s

# Get initial admin password
kubectl -n argocd get secret argocd-initial-admin-secret   -o jsonpath="{.data.password}" | base64 -d

# Port-forward to access UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
Important: Change the admin password immediately after first login and delete the argocd-initial-admin-secret. It contains the plain initial password and has no business existing after setup.

Repository structure that scales

How you structure your GitOps repo determines how painful your life will be at 50 apps vs 5. The pattern I use:

gitops-repo/
  apps/                    # ArgoCD Application manifests
    api-service.yaml
    worker-service.yaml
    frontend.yaml
  clusters/
    production/
      kustomization.yaml   # points to apps/ with prod overlays
    staging/
      kustomization.yaml
  base/                    # shared Helm values or k8s manifests
    api-service/
      deployment.yaml
      service.yaml
      hpa.yaml

Your first Application manifest

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: api-service
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/your-org/gitops-repo
    targetRevision: main
    path: base/api-service
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true      # delete resources removed from Git
      selfHeal: true   # revert manual kubectl changes
    syncOptions:
      - CreateNamespace=true

The prune and selfHeal decision

prune: true means resources deleted from Git get deleted from the cluster. selfHeal: true means if someone runs kubectl edit directly on a resource, ArgoCD reverts it within minutes. These are powerful but need team agreement first.

My recommendation: Enable both in staging from day one so your team learns the GitOps discipline early. In production, enable selfHeal but keep prune manual initially — accidental resource deletion in prod is expensive.

Progressive delivery with Argo Rollouts

ArgoCD pairs with Argo Rollouts to give you canary and blue-green deployments as Kubernetes-native resources:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: api-service
spec:
  strategy:
    canary:
      steps:
      - setWeight: 10     # 10% traffic to new version
      - pause: {{duration: 5m}}
      - setWeight: 50
      - pause: {{duration: 10m}}
      - setWeight: 100    # full rollout if no issues

If error rates spike during the canary phase, you roll back with a single Git revert — ArgoCD picks it up within seconds.

Common mistakes to avoid

← Back to all articles