From manual deployment to Infrastructure as Code, why Weaveworks introduced the term GitOps in 2017, the problems it solves, and why the pull model beats the push model.

In episode 0 we prepared all the tools and verified them. Now it's time to step back from the keyboard and ask the single most important question: why does GitOps exist? Because before understanding a tool, we must first understand what problem it solves — and choosing a tool without understanding the problem is a fragile decision.
This episode is like reading history before buying a machine: once you know how painful manual deployment was and how fragile scripts are, you'll understand why the world moved to GitOps. In this episode we'll cover the evolution of deployment practices, the birth of the term GitOps by Weaveworks, the problems it solves, the four principles of GitOps, the push vs pull model comparison, and the benefits you can enjoy.
The journey toward GitOps spans four eras, and each era was born as an answer to the pain of the previous one.
In the early days, deploying an application meant SSH-ing into the server, copying artifacts, running processes manually, then hoping everything worked. Each server was treated as an individual. There was no record of who changed what; everything depended on the memory and discipline of the person executing.
The problem is obvious: humans are inconsistent. One person forgets to change an environment config, another installs a different version, and there's not a single auditable trace. This is the root of many classic production failures.
As an answer, engineers started writing shell scripts to automate the sequence of deployment steps:
#!/bin/bash
set -euo pipefail
kubectl apply -f configmap.yaml
kubectl apply -f secret.yaml
kubectl set image deployment/api api=ghcr.io/arman/api:v1.2.0
kubectl rollout status deployment/apiThis script is imperative: it spells out the step-by-step process to reach the end result. Better than manual, but fragile. kubectl set image overwrites state directly in the cluster, and if two people run different scripts at the same time, the end result is decided by whoever executed last — not by whoever was right.
Next came CI/CD: Jenkins, GitLab CI, GitHub Actions, and friends automated build, test, and deploy. This was a huge leap — deployment became documented in pipelines, and failures could be detected immediately.
But there's an inherent structural weakness: the push model. Pipelines hold cluster credentials and push changes to production. The more pipelines, the more credentials spread around. And because deploys are driven from outside the cluster, it's hard to answer a simple question: "is the cluster actually in the state we want?"
IaC declares infrastructure as code: terraform for cloud, kustomize and helm for Kubernetes. Now we can review infrastructure in pull requests and audit it through Git history. IaC solves how infrastructure is defined — but not yet how the changes reach and are maintained on the cluster.
That's where GitOps completes the puzzle: IaC provides the definition, Git provides the audit trail, and operators like ArgoCD provide the executor that continuously reconciles. Git becomes the single source of truth, and the cluster no longer waits for an external push — it pulls its own desired state from Git.
The term GitOps was first coined by Weaveworks in 2017 as an operating model for Kubernetes: Git as the single source of truth for a declarative system, with an automated agent running inside the cluster that materializes and maintains that state.
In short: "what's in Git is the truth. The cluster must match Git. Always."
GitOps was born to solve real problems in the field:
| Problem | Symptom | GitOps Solution |
|---|---|---|
| Configuration drift | Cluster deviates from the desired configuration | Continuous reconciliation restores the state |
| Manual deployment errors | Human errors during deploy | Changes only via Git + PR review |
| Lack of auditability | Don't know who changed what | Git history is a complete audit trail |
| Complicated rollback | Hard to return to a previous state | git revert + automatic sync |
| Environment inconsistency | dev and prod differ wildly | One source definition for all |
| Messy access control | Many credentials spread across pipelines | Pull model: only ArgoCD needs access |
| Deployment visibility | Don't know the actual status | Sync and health status visible in real-time |
Important
Configuration drift is the main enemy. Imagine a production Deployment manually changed by someone via kubectl scale deployment api --replicas=10. The system isn't wrong — but the definition in Git (e.g. replicas: 3) and the cluster state (10 replicas) now differ. Drift like this accumulates silently and becomes the root of unexpected failures.
According to the Weaveworks definition, a truly GitOps system must satisfy four principles:
This difference determines the security and reliability architecture of your deployment:
| Aspect | Push (traditional CI/CD) | Pull (GitOps) |
|---|---|---|
| Deployment trigger | External pipeline | Change in Git detected by the agent |
| Cluster access | Many tools hold credentials | Only the in-cluster operator |
| Actual state | Not continuously monitored | Always reconciled |
| Rollback | Dedicated pipeline | Revert Git, the agent follows |
| Audit | Pipeline logs | Git commit history |
The pull model is more secure because cluster credentials aren't spread externally, and more reliable because the cluster state is continuously forced back to the desired state.
In short, here's what you get:
This episode builds the conceptual foundation for the whole series:
Now you know why GitOps exists. In episode 2 we'll cover the GitOps ecosystem and an ArgoCD overview: the competitive landscape with Flux and Jenkins X, ArgoCD's component architecture, its core concepts, and how the reconciliation loop works. See you there!