All Modules Why GitOps Concepts Hands-on Lab Cheat Sheet

GitOps with Argo CD

Make Git the single source of truth — commit a change and the cluster syncs itself.

Advanced A3 · Argo CD watches your Helm chart in Git and reconciles the cluster to match.

Advanced GitOps ~65 min

What You'll Learn

  • Explain GitOps and how it differs from push-based deploys
  • Install Argo CD on your cluster and reach its UI/CLI
  • Define an Argo CD Application pointing at your Helm chart in Git
  • Enable auto-sync, self-heal, and prune
  • Deploy by git push — and watch Argo correct manual drift automatically
  • Roll back through Git (and Argo's history)

Prerequisites: A2 (Helm) — we deploy the notes-chart you built. A running k3d cluster and a GitHub account.

Why GitOps Exists

In A2 you deployed with helm upgrade from your laptop. That's push-based: a human (or CI runner) pushes changes into the cluster. It works, but it has problems — who ran what, when? Is the cluster still what we think it is? What if someone kubectl edits something by hand?

Push-based deploys drift

There's no single record of "what should be running," manual hotfixes silently diverge from your YAML (drift), and rollback means remembering the last good command. Credentials to the cluster also have to live in your CI system.

GitOps flips it: a Git repo holds the desired state of the cluster, and an in-cluster agent (Argo CD) continuously pulls from Git and makes reality match. Git becomes the single source of truth and the audit log.

Push (helm/kubectl)GitOps (Argo CD)
TriggerYou run a commandYou merge a commit
Source of truthWhatever's in the clusterThe Git repo
DriftGoes unnoticedDetected & auto-corrected
AuditShell history, maybeFull Git history
RollbackRe-run an old commandgit revert
Cluster credsIn your CIStay inside the cluster

How Argo CD Thinks

Argo CD runs in your cluster and loops forever: read desired state from Git → compare to live state → reconcile.

┌────────── Git repo (desired state) ──────────┐ │ notes-chart/ (Helm chart + values) │ └───────────────────────┬───────────────────────┘ │ Argo CD pulls & compares ▼ ┌──────── Argo CD (in-cluster controller) ───────┐ │ diff desired vs live → SYNC → reconcile │ └───────────────────────┬─────────────────────────┘ ▼ Kubernetes cluster (live state)
TermWhat it is
ApplicationAn Argo CD object: "deploy this path/chart from this repo into this namespace."
SyncApplying the desired state to the cluster.
Sync statusSynced (matches Git) or OutOfSync (drifted).
Self-healAuto-revert any manual change back to Git's version.
PruneDelete resources removed from Git.
App-of-AppsOne Application that manages many others — how teams scale GitOps.

Hands-on Lab: Self-Syncing Deployments

We'll put the notes-chart in Git and let Argo CD deploy and maintain it. Use your k3d cluster from A1/A2.

1

Push the chart to a Git repo

Create a repo (e.g. notes-gitops) containing your notes-chart/ from A2, and push it to GitHub:

mkdir notes-gitops && cd notes-gitops cp -r ../notes-chart . git init && git add . && git commit -m "notes-chart" git branch -M main git remote add origin https://github.com/YOUR_USERNAME/notes-gitops.git git push -u origin main
2

Install Argo CD

kubectl create namespace argocd kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml kubectl -n argocd rollout status deploy/argocd-server # wait until Ready
3

Open the Argo CD UI

Get the auto-generated admin password and port-forward the UI:

kubectl -n argocd get secret argocd-initial-admin-secret \ -o jsonpath="{.data.password}" | base64 -d; echo kubectl port-forward -n argocd svc/argocd-server 8081:443

Browse to https://localhost:8081 (accept the self-signed cert), log in as admin. Optionally log in with the CLI too:

argocd login localhost:8081 --username admin --insecure
4

Declare the Application

This is the heart of GitOps: an Application telling Argo CD which repo/chart to deploy where. Save as application.yaml (point repoURL at your repo):

apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: notes namespace: argocd spec: project: default source: repoURL: https://github.com/YOUR_USERNAME/notes-gitops.git targetRevision: main path: notes-chart helm: valueFiles: - values.yaml destination: server: https://kubernetes.default.svc namespace: notes syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=true
kubectl apply -f application.yaml argocd app list # 'notes' appears

The "aha!" moment

Within seconds Argo CD pulls your chart from Git and deploys the whole notes stack — you never ran helm install. The app's tile in the UI turns green: Synced & Healthy.

5

Watch a sync & explore the tree

argocd app get notes # sync status, health, resources kubectl get pods -n notes # web + db, deployed by Argo

In the UI, click the notes app to see the live resource tree (Deployment → ReplicaSet → Pods, plus the StatefulSet and Services) with health dots.

6

Deploy by committing — the GitOps loop

No more helm upgrade. Change the chart in Git and Argo rolls it out. Bump replicas in your repo:

# in notes-gitops/notes-chart/values.yaml, change web.replicas: 2 -> 4 git commit -am "scale web to 4" git push

Argo detects the new commit (auto, or click Refresh) and syncs — a third and fourth web pod appear. Your git push was the deploy.

7

Watch self-heal correct drift 🔥

This is GitOps' superpower. Manually change the cluster — Argo reverts it because Git says otherwise:

kubectl scale deploy/notes-web -n notes --replicas=1 kubectl get pods -n notes -w # Argo scales it right back to 4

No more snowflake clusters

With selfHeal: true, the cluster can't drift from Git — any out-of-band change is reverted within seconds. The repo is the truth, always.

8

Roll back through Git

A bad change went out? Revert the commit — Argo syncs the cluster back automatically:

git revert HEAD # undo the last change in Git history git push # Argo reconciles the cluster to match # or roll back within Argo's own history: argocd app history notes argocd app rollback notes <REVISION>

Rollback = revert a commit

Your deployment history is your Git history. Every change is reviewable, attributable, and reversible with one commit.

9

Clean up

argocd app delete notes # removes the app + its resources (prune)

Argo CD Cheat Sheet

CommandWhat it does
argocd login HOSTLog in to the Argo CD API
argocd app listList all Applications
argocd app get NAMESync status, health, resource tree
argocd app sync NAMEManually trigger a sync
argocd app diff NAMEShow desired-vs-live differences
argocd app history NAMEDeployment revisions
argocd app rollback NAME NRoll back to revision N
argocd app set NAME -p k=vOverride a Helm parameter
argocd app delete NAMERemove the app (and prune)
kubectl get applications -n argocdApps are just CRDs — manage as YAML

The mindset shift

You almost never run argocd app sync in steady state — you change Git and let Argo do the rest. The CLI is mostly for inspection and the occasional manual nudge.

Troubleshooting

SymptomLikely cause & fix
App stuck OutOfSyncAuto-sync off — enable it, or run argocd app sync. Check the diff.
ComparisonError / repo not foundWrong repoURL/path, private repo with no creds — add the repo in Settings.
Image won't pull on k3dArgo deploys fine, but k3d still needs the local image imported (k3d image import).
Manual edits keep revertingThat's selfHeal working as designed — change Git, not the cluster.
Can't reach the UIKeep the port-forward running; use https:// and accept the cert.
Resources not deletedprune is off — enable it so removed-from-Git means removed-from-cluster.

Your Challenge

  • Create a second Application notes-dev using values-dev.yaml in its own namespace — one repo, two environments.
  • Commit the Application manifests themselves to Git and manage them with an App-of-Apps.
  • Add sync waves so the database deploys before the web app (annotation argocd.argoproj.io/sync-wave).
  • Turn off self-heal and watch an OutOfSync badge appear when you edit a resource.
  • Bonus: set a notification (or just argocd app wait in CI) when a sync completes.
# a root Application whose source path is a folder of Application YAMLs: spec: source: repoURL: https://github.com/YOU/notes-gitops.git path: apps # folder containing notes.yaml, notes-dev.yaml... targetRevision: main # Argo deploys every Application it finds there -> App-of-Apps

Recap & What's Next

You can now

Run Argo CD, declare an Application that deploys your Helm chart from Git, enable auto-sync/self-heal/prune, deploy by committing, watch drift auto-correct, and roll back with git revert. Git is now your control plane.

Next up: A4 — Progressive Delivery, where you'll ship new versions safely with canary and blue-green rollouts — gradually shifting traffic and auto-rolling-back on failure, all driven from Git.

GitOps with Argo CD

Objectives Why GitOps How Argo Thinks Hands-on Lab Cheat Sheet Troubleshooting Challenge Recap