GitOps Patterns with Python — Core Concepts

The four GitOps principles

GitOps was formalized by Weaveworks in 2017, and the Open GitOps project defines four core principles:

  1. Declarative — the desired state of the system is described in files, not built through imperative commands
  2. Versioned and immutable — the desired state is stored in Git, providing a full audit trail and the ability to revert
  3. Pulled automatically — agents inside the cluster pull the desired state from Git and apply it (pull-based, not push-based)
  4. Continuously reconciled — software agents compare actual state to desired state and correct any drift

Push vs. pull model

Traditional CI/CD is push-based: a pipeline builds code and pushes it to production. GitOps prefers the pull model: an agent running inside the cluster continuously watches the Git repository and pulls changes when it detects them.

The pull model is more secure because nothing outside the cluster needs credentials to deploy inside it. The agent already has access — it just reads from Git.

How Python fits in

Python serves multiple roles in GitOps workflows:

Configuration generationKubernetes manifests and Helm values can be complex. Python scripts or tools like Kapitan and CDK8s generate these files from higher-level templates, then commit the results to Git.

Custom reconciliation — while ArgoCD and Flux handle standard Kubernetes resources, some teams need custom reconciliation logic for databases, DNS records, or external services. Python operators (using Kopf or the Kubernetes Python client) bridge this gap.

Pipeline automation — when a new container image is built, a Python script updates the image tag in the Git repository, creating the commit that triggers the GitOps deployment. This is the “image updater” pattern.

Drift detection — Python scripts compare what’s in Git against what’s running, alerting when manual changes have been made outside the GitOps flow.

The GitOps repository structure

Most teams maintain two repositories:

  • Application repo — contains source code, Dockerfile, and CI pipeline
  • Config repo — contains Kubernetes manifests, Helm values, or Kustomize overlays. This is the “source of truth”

When CI builds a new image, it updates the config repo. The GitOps agent sees the change and deploys.

Common misconception

“GitOps is just CI/CD with Git.” The critical difference is the reconciliation loop. CI/CD runs once and stops. GitOps continuously compares desired state (Git) with actual state (cluster) and corrects drift. If someone manually changes a deployment, the GitOps agent reverts it. This self-healing property is what makes GitOps fundamentally different from traditional deployment pipelines.

When GitOps works best

GitOps excels for Kubernetes-based infrastructure where the desired state can be fully described in YAML. It’s harder for stateful systems, legacy applications, or infrastructure that requires imperative provisioning steps. Many teams adopt GitOps gradually — starting with stateless services and expanding as they build confidence.

The one thing to remember: GitOps is not just “deploy from Git” — it’s a continuous reconciliation loop where software agents ensure reality matches the desired state declared in Git, and Python tools help generate configs, update image tags, and handle custom reconciliation.

pythongitopskubernetesdevops

See Also