Command Palette

Search for a command to run...

Hectal

Mission 1.2 · Stage 1 — GitOps with Argo CD

Your First Application: Sync and Health

Goal: ShopLite's web Deployment and Service deployed by Argo CD from Git, with a deploy done purely by a commit.

40 min Free 6 steps 2 break-it drills

By the end of this mission

  • Write an Argo CD Application resource
  • Read Sync status (Synced/OutOfSync) and Health status (Healthy/Progressing/Degraded)
  • Deploy a new version with a Git commit, and roll back with git revert
  • Use the argocd CLI to inspect diffs and history

Part 1

Understand it first

The Application resource

An Application connects a SOURCE (repo URL, revision, path, and how to render it) to a DESTINATION (cluster and namespace). Argo CD renders the source, compares it with what's live, and reports two independent statuses.

SYNC STATUS answers 'does the cluster match Git?' (Synced / OutOfSync). HEALTH STATUS answers 'is what's running actually working?' (Healthy, Progressing, Degraded, Missing, Suspended). An app can be Synced but Degraded: Git was applied perfectly, and the new pods crash. Health checks are built in for standard kinds (a Deployment is Healthy when its rollout completed) and can be customised in Lua for CRDs.

Part 2

Your project after this mission · 3 files change

shoplite-gitops/
  • shoplite-gitops/
    • apps/
      • web/
        • deployment.yamlnew
        • service.yamlnew
    • argocd/
      • web-dev.yamlnew
    • README.md

Part 3

Build it, step by step

  1. 1

    Write the manifests

    The same Deployment you wrote in the Kubernetes course, with probes and resources. nginxdemos/hello stands in for the ShopLite web image; it shows its version in the page, so you can watch deploys happen.

    shoplite-gitops/apps/web/deployment.yamlwhole fileyaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: web
      labels: { app: web }
    spec:
      replicas: 2
      selector:
        matchLabels: { app: web }
      template:
        metadata:
          labels: { app: web }
        spec:
          containers:
            - name: web
              image: nginxdemos/hello:0.3
              ports: [{ containerPort: 80 }]
              readinessProbe:
                httpGet: { path: /, port: 80 }
              resources:
                requests: { cpu: 50m, memory: 32Mi }
                limits: { memory: 64Mi }
  2. 2

    And the Service

    A ClusterIP Service in front of the pods.

    shoplite-gitops/apps/web/service.yamlwhole fileyaml
    apiVersion: v1
    kind: Service
    metadata:
      name: web
    spec:
      selector: { app: web }
      ports: [{ port: 80, targetPort: 80 }]
  3. 3

    Declare the Application

    The Application itself is YAML too, and it lives in the same repo, so even 'what Argo CD manages' is in Git. CreateNamespace=true lets Argo create shoplite-dev. There's no automated block yet, so Argo will only report differences; you'll sync by hand first to see each step.

    shoplite-gitops/argocd/web-dev.yamlwhole fileyaml
    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
      name: web-dev
      namespace: argocd
    spec:
      project: default
      source:
        repoURL: https://github.com/<you>/shoplite-gitops.git
        targetRevision: main
        path: apps/web
      destination:
        server: https://kubernetes.default.svc
        namespace: shoplite-dev
      syncPolicy:
        syncOptions:
          - CreateNamespace=true
  4. 4

    Push, register, and sync

    After this one-time kubectl apply of the Application, you won't use kubectl to deploy again. Before the first sync, the app is OutOfSync and Missing: Git has resources the cluster doesn't.

    terminal
    $ git add . && git commit -m 'web: initial deploy to dev' && git push
    kubectl apply -f argocd/web-dev.yaml
    argocd app get web-dev | grep -E 'Sync Status|Health'
    argocd app sync web-dev
    argocd app wait web-dev --health
    ── expected output ──
    Sync Status: OutOfSync from main (a1b2c3d)
    Health Status: Missing
    ...
    GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE
    Service shoplite-dev web Synced Healthy service/web created
    apps Deployment shoplite-dev web Synced Progressing deployment.apps/web created
    ...
    Health Status: Healthy
  5. 5

    Deploy by commit

    Change the image tag in Git. That's the whole deploy. Argo polls repos every 3 minutes by default; a Git webhook to /api/webhook makes it near-instant. argocd app diff shows exactly what will change, like terraform plan.

    terminal
    $ sed -i 's/hello:0.3/hello:0.4/' apps/web/deployment.yaml
    git commit -am 'web: 0.3 → 0.4' && git push
    argocd app diff web-dev --refresh
    argocd app sync web-dev && argocd app history web-dev
    ── expected output ──
    ===== apps/Deployment shoplite-dev/web ======
    < image: nginxdemos/hello:0.3
    > image: nginxdemos/hello:0.4
    ...
    ID DATE REVISION
    0 2026-09-26 10:02:11 +0530 IST main (a1b2c3d)
    1 2026-09-26 10:09:47 +0530 IST main (d4e5f6a)
  6. 6

    Roll back the GitOps way

    argocd app rollback exists, but it makes the cluster differ from Git, and with auto-sync on (next mission) Argo would immediately undo it. The GitOps rollback is git revert: history shows exactly who rolled back, when, and why.

    terminal
    $ git revert --no-edit HEAD && git push
    argocd app sync web-dev
    kubectl -n shoplite-dev get deploy web -o jsonpath='{.spec.template.spec.containers[0].image}'
    ── expected output ──
    nginxdemos/hello:0.3

Checkpoint — you should now have

  • ✓argocd app get web-dev shows Synced and Healthy.
  • ✓You deployed 0.4 and rolled back to 0.3 using only Git commits.
  • ✓argocd app history web-dev lists each deploy with its Git revision.

Part 4

Break it on purpose

Make each change, run the command, and read the error before revealing the diagnosis. Recognising these messages on sight is what makes you fast on a real team. Undo the change afterwards.

Break #1

Synced but broken

Set the image to nginxdemos/hello:does-not-exist, commit, push, and sync.

terminal
$ argocd app get web-dev | grep -E 'Sync Status|Health'
kubectl -n shoplite-dev get pods
── what you'll see ──
Sync Status: Synced to main (e7f8a9b)
Health Status: Progressing
NAME READY STATUS RESTARTS
web-5d8c7b9f6-abcde 1/1 Running 0
web-5d8c7b9f6-fghij 1/1 Running 0
web-7c9d8e6f5-klmno 0/1 ImagePullBackOff 0

Break #2

Point at a path that doesn't exist

Change the Application's path to apps/webb and apply it.

terminal
$ argocd app get web-dev
── what you'll see ──
CONDITION MESSAGE
ComparisonError Failed to load target state: failed to generate manifest for source 1 of 1: rpc error: code = Unknown desc = apps/webb: app path does not exist

Part 5

Interview questions from this mission

01

What's the difference between Sync status and Health status in Argo CD?

02

How do you roll back in GitOps?

0/4 · 0%