SynfraCore
Synfracore
Start Learning
Navigation

Academies

Platform

RoadmapsLabsCertificationsInterviewPYQsAI AssistantCareer
Start Learning Free Learning Roadmaps

ArgoCDFundamentals

Core concepts and commands — hands-on from the start

📄
Last updated Jul 2026
Expert Content

ArgoCD — Fundamentals

Analogy — An Application resource is like a standing delivery instruction, not a one-time order. You're not telling ArgoCD "deploy this once" — you're telling it "this Git path is what should always be running in this namespace, forever, check back and correct it whenever they diverge." That's why Sync status (Synced/OutOfSync) is really a live comparison result, re-evaluated continuously, not a one-time deployment log entry.

Git repo (path: apps/my-app/prod)  ⇄  ArgoCD (continuously compares)  ⇄  Cluster namespace
        "desired state"                                                   "actual state"
                                    │
                        OutOfSync? → sync (apply the diff)

Core Concepts

Application: ArgoCD resource linking a Git repo path to a K8s cluster/namespace
Repository: Git repo containing K8s manifests (plain YAML, Helm, Kustomize)
Sync:        Make cluster state match Git state
Drift:       Cluster state differs from Git (detected automatically)

Sync status:  Synced | OutOfSync
Health status: Healthy | Progressing | Degraded | Missing

Install ArgoCD

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

# Wait for pods
kubectl wait --for=condition=Ready pod -l app.kubernetes.io/name=argocd-server -n argocd

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

# Port forward to access UI
kubectl port-forward svc/argocd-server -n argocd 8080:443

# Login with CLI
argocd login localhost:8080
argocd account update-password

Application Definition

yaml
# application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app-production
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io  # Cascade delete

spec:
  project: default

  source:
    repoURL: https://github.com/myorg/k8s-configs
    targetRevision: HEAD     # Branch, tag, or commit SHA
    path: apps/my-app/prod   # Path within repo

    # For Helm charts
    helm:
      valueFiles:
        - values.yaml
        - values-prod.yaml
      parameters:
        - name: image.tag
          value: "1.2.3"

  destination:
    server: https://kubernetes.default.svc  # In-cluster
    namespace: production

  syncPolicy:
    automated:
      prune: true       # Delete resources removed from Git
      selfHeal: true    # Revert manual changes to cluster
    syncOptions:
      - CreateNamespace=true
      - ApplyOutOfSyncOnly=true
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

App of Apps Pattern

yaml
# root-app.yaml — single application that manages all other applications
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root-app
  namespace: argocd
spec:
  source:
    repoURL: https://github.com/myorg/k8s-configs
    targetRevision: HEAD
    path: argocd/apps  # This directory contains other Application YAMLs
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

# argocd/apps/ directory contains:
# - api-app.yaml (Application for API service)
# - frontend-app.yaml (Application for frontend)
# - monitoring-app.yaml (Application for Prometheus/Grafana stack)

Image Updater

yaml
# Automatically update image tags when new images are pushed
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  annotations:
    argocd-image-updater.argoproj.io/image-list: |
      app=registry.example.com/my-app
    argocd-image-updater.argoproj.io/app.update-strategy: latest
    argocd-image-updater.argoproj.io/write-back-method: git
spec:
  source:
    helm:
      parameters:
        - name: image.tag
          value: latest  # Will be updated by image updater

CLI Common Commands

bash
# Application management
argocd app list
argocd app get my-app-production
argocd app sync my-app-production
argocd app sync my-app-production --dry-run    # Preview sync
argocd app diff my-app-production              # What will change

# Rollback
argocd app history my-app-production
argocd app rollback my-app-production 5  # Roll back to revision 5

# Manual override (will be reverted by selfHeal)
argocd app set my-app-production --parameter image.tag=v1.2.3

# Project management
argocd proj list
argocd proj create production \
  --dest https://k8s.prod.example.com,production \
  --src https://github.com/myorg/k8s-configs

# Repository management
argocd repo add https://github.com/myorg/k8s-configs \
  --username git \
  --password $GITHUB_TOKEN

Try It (2 Minutes)

Using an app you've already created (or ArgoCD's own bundled example app):

1.argocd app diff my-app-production — even with nothing changed, this shows you exactly how ArgoCD compares Git's rendered manifests against the cluster's live objects, field by field.
2.Change one value in Git (e.g. bump replicaCount in values-prod.yaml) and push the commit.
3.Run argocd app diff my-app-production again — it now shows the specific field that differs, before you've synced anything. argocd app sync my-app-production applies exactly that diff. This is the standing-delivery-instruction idea made concrete: ArgoCD already knew about the mismatch the moment Git changed, it just hadn't corrected it yet.
Share:
Join our Community
Daily tips, job alerts, interview help — join engineers learning together
Up Next
ArgoCDIntermediate
Real-world patterns, best practices, and deeper topics
Also Worth Exploring
← Back to all ArgoCD modules
InstallationIntermediate