ssprkd.io
GitOps & Delivery
Lesson 1 of 6

GitOps principles

Make Git the single source of truth so a controller continuously reconciles your cluster, catching drift and self-healing without anyone touching prod.

Watch

Speed
📖 Read this walkthrough — every command, and why
GitOps Principles — git is the source of truth, an agent reconciles the cluster to it

Mental model: deploying by hand doesn't scale, and nobody can tell you what's actually
running. GitOps replaces "push kubectl at the cluster" with four tenets you can watch in
Argo CD:

  1. Declarative      — you describe the desired end state, not the steps to get there.
  2. Versioned in git — that repo is the single source of truth; every sync pins an exact commit.
  3. Pulled           — an agent running INSIDE the cluster pulls desired state from git and applies it.
  4. Reconciled       — the agent keeps comparing live vs git and drives any drift back (self-heal).

Here an Argo CD Application named guestbook points at a git repo + path and says "make the
cluster look like this." Argo's application-controller (in-cluster) does the pulling and reconciling.

1 · The Application declares desired state FROM GIT
    kubectl apply -f guestbook-app.yaml       # source: repo + path -> destination cluster/namespace
    # application.argoproj.io/guestbook created

2 · Inspect it — SYNC tells you live matches git, HEALTH tells you the workload is up
    kubectl get application guestbook -n argocd
      NAME        REPO                                                  PATH        SYNC     HEALTH
      guestbook   https://github.com/argoproj/argocd-example-apps.git   guestbook   Synced   Healthy
    # Synced  = live cluster == the manifests in git at the pinned revision
    # Healthy = the resources Argo created are actually running/ready

3 · The workload Argo created FROM GIT — nobody ran kubectl by hand
    kubectl get deploy,svc -l app=guestbook-ui
      NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
      deployment.apps/guestbook-ui   1/1     1            1           29s

      NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
      service/guestbook-ui   ClusterIP   10.96.165.176   <none>        80/TCP    29s
    # Both the Deployment and the Service came straight from the guestbook path in the repo.

4 · Git is the source of truth — the sync revision pins a REAL commit
    # Synced @ revision 8088f4c0d970abb09e250248cc97e35623447cb5
    A full commit SHA you can review, revert, and audit. To change production you change git,
    not the cluster. The canonical rollback is `git revert <bad-commit>` -> the controller
    reconciles the cluster back to the prior declared state.

5 · Continuous reconciliation / self-heal — delete a synced resource; Argo restores it
    kubectl delete deploy guestbook-ui        # drift: live no longer matches git
    # with selfHeal=true the application-controller notices and recreates it
    kubectl get deploy guestbook-ui
      NAME           READY   UP-TO-DATE   AVAILABLE   AGE
      guestbook-ui   1/1     1            1           25s
    # Ready again seconds later. The controller doesn't apply once and walk away —
    # it keeps driving live state back toward what git declares. THAT reconciliation is GitOps.

What each part does
    Application (CRD)              declares source (repo+path) -> destination + sync policy
    SYNC = Synced                 live cluster == git at the pinned revision
    HEALTH = Healthy              the created resources are running/ready
    revision 8088f4c0...          the exact git commit that Synced state was computed from
    selfHeal=true                 auto-correct out-of-band drift back to git

Notes and gotchas
  - Git is truth. Don't `kubectl edit` prod. A hand edit is drift the controller will overwrite
    (or, with selfHeal off, it just shows the app OutOfSync until you fix git). Either way your
    change is untracked and gets lost.
  - The controller never writes live state back INTO git. Bumping replicas with `kubectl scale`
    while git still says 3 gets reconciled back to 3 — persist it by editing the manifest.
  - Pulled, not pushed: the agent lives in-cluster and pulls from git, so cluster-admin creds
    never leave the cluster for an external CI system — you only grant the agent repo read access.
  - Declarative vs imperative: declarative states the end result and lets the reconciler figure
    out how; imperative issues ordered step-by-step commands. GitOps needs declarative specs so
    they can be stored in git and continuously reconciled.

Verify:  kubectl get application guestbook -n argocd -o wide      # expect SYNC=Synced, HEALTH=Healthy
Gotcha:  Synced means matches git, NOT "correct" — if you commit a broken manifest, Argo will
         faithfully sync the cluster to broken. Git being the source of truth cuts both ways.