GitOps Workflow Diagram: Pull-Based Delivery with Argo CD or Flux

A GitOps workflow diagram explained: the OpenGitOps principles, app and config repos, pull-based sync with Argo CD or Flux, promotion by pull request and rollback.

· Founder & developer

Published

GitOps Workflow Diagram: Pull-Based Delivery with Argo CD or Flux

In a classic pipeline, CI builds the code and then pushes the result into the cluster with kubectl apply or helm upgrade. It works, but the pipeline needs admin credentials for every cluster, nobody can say for sure what is running without asking the cluster, and a hand-edited deployment silently differs from what the repo says.

GitOps flips the direction. Git holds the desired state, and an agent inside the cluster keeps pulling it and making the cluster match. This post explains the principles, the two-repo workflow most teams use, how promotion and rollback work, and draws the whole flow.

The four principles

The CNCF's OpenGitOps project defines GitOps with four principles:

  1. Declarative: the desired state of the system is expressed declaratively.
  2. Versioned and immutable: that state is stored in a way that keeps a complete, immutable version history, which in practice means Git.
  3. Pulled automatically: software agents pull the desired state from the source.
  4. Continuously reconciled: agents keep comparing the actual state with the desired state and correct the difference.

The third point is what separates GitOps from "deploy from a pipeline that reads Git". The cluster pulls; nothing outside pushes into it.

Two repos: code and config

Most teams separate two kinds of change:

  • The app repo holds source code. CI builds it, runs tests, scans it and pushes an immutable image tag to a registry.
  • The config repo holds the Kubernetes manifests, Helm values or Kustomize overlays for every environment. It describes what should run where, including image tags.

The link between them is a small, explicit change: CI, or an image automation tool, opens a pull request in the config repo that bumps the image tag for staging. That pull request is the deployment request, with a review and an audit trail.

The controller in the cluster

Argo CD and Flux are the two widely used GitOps controllers. Both run inside the cluster, poll or receive webhooks from the config repo, render the manifests, compare them with the live objects, and apply the difference.

Their reconciliation settings decide how strict the system is:

  • Automatic sync: apply new commits without a person pressing a button.
  • Pruning: delete objects that were removed from Git.
  • Self-heal: revert changes made directly in the cluster. With Argo CD's automated sync options, self-heal is a separate switch from auto-sync.

Self-heal is the setting that makes Git the actual source of truth. Without it, a kubectl edit at 3 a.m. becomes permanent and invisible.

Promotion and rollback

Environments are folders, overlays or files in the config repo. Promotion means copying a version from one to the next:

  1. The pull request bumps the staging tag; staging updates within minutes of the merge.
  2. Tests and checks run against staging.
  3. A second pull request bumps production to the same tag. Merging it is the production deploy.

Rollback is git revert of that merge. The controller sees the old tag and applies it. Because the whole history is in Git, the question "what was running in production last Tuesday at 14:00?" has an exact answer.

Who opens the pull request

There are two common ways to connect a new image to the config repo:

  • CI opens it. The last pipeline step clones the config repo, changes one line, commits to a branch and opens a pull request. It is explicit and easy to debug, and the pipeline only needs a token for that one repository.
  • An image automation tool commits it. Flux's image automation controllers and the Argo CD Image Updater project can watch a registry, pick new tags that match a policy, and write them back to Git. Useful for staging environments that should always run the latest build.

Many teams combine them: automation keeps staging current, while production changes always arrive as a reviewed pull request from a person or a release job. Whichever you choose, write it on the diagram, because "how does a new version get here?" is the first question anyone asks about a GitOps setup.

One release, end to end

Follow version 1.8.0 of a shop service from commit to production:

  1. A developer merges a change to the app repo. CI runs tests, builds the image, scans it and pushes shop:1.8.0 to the registry.
  2. CI opens a pull request in the config repo that changes the staging tag from 1.7.3 to 1.8.0. A reviewer approves and merges it.
  3. Within a minute or two, the controller notices the new commit, renders the staging manifests and updates the deployment. Kubernetes rolls out new pods, which pull the image from the registry.
  4. Smoke tests pass on staging. The release owner opens a second pull request that sets production to 1.8.0.
  5. After that merge, production rolls out the same way. If error rates rise, reverting the merge commit puts 1.7.3 back.

At no point did anything outside the cluster need cluster credentials, and every step left a commit behind.

Secrets

Plain secrets cannot go into Git. Common approaches:

  • Encrypted in Git, with tools such as Sealed Secrets or SOPS, decrypted only inside the cluster.
  • References in Git, values elsewhere, with an operator such as External Secrets that reads from a secrets manager.

Either way, the config repo stays reviewable and the secret values never appear in a diff.

The architecture diagram

A developer pushes to an app repo; CI builds, tests and pushes image 1.8.0 to a registry and opens a pull request bumping the staging tag in a config repo. A GitOps controller in the Kubernetes cluster pulls the config repo and applies it to the staging and production namespaces.

12 components · 8 connections

Open in Archboard
Diagram contents
  • Developer
  • App repo: code
  • CI: build, test, scan
  • Container registry
  • Config repo: desired state
  • Kubernetes cluster
  • GitOps controller
  • staging
  • shop v1.8.0
  • production
  • shop v1.7.3
  • push
  • trigger
  • image 1.8.0
  • PR: bump staging tag
  • pull every few minutes
  • apply
  • nodes pull images
A GitOps workflow. CI builds and pushes an image, then opens a pull request that changes the image tag in the config repo; a controller inside the cluster pulls the config repo, applies the change to staging or production, and reverts manual drift.

How to read it:

  • Top row, the build: a developer pushes to the app repo, CI builds and tests image 1.8.0 and pushes it to the registry.
  • Middle: CI opens a pull request that bumps the staging tag in the config repo. This is the only place where CI touches deployment.
  • Bottom, the cluster: the GitOps controller pulls the config repo (dashed), applies it to the staging namespace, which now runs 1.8.0, and to production, which still runs 1.7.3 until its own pull request is merged. Nodes pull images from the registry (dotted).
  • The Markdown block states the workflow rules: promotion by pull request, rollback by revert, drift reverted by self-heal.

What changes for the team

  • CI loses cluster credentials. The cluster reaches out; the pipeline only needs write access to a repo.
  • Reviews cover deployments. Who deployed what, when and why is in the pull request history.
  • Drift becomes visible. The controller shows out-of-sync resources instead of hiding them.
  • Debugging moves. "Why did this not deploy?" is answered by the controller's sync status and events, so make them visible to the people who merge.

What to put on a GitOps diagram

  • Both repos, and the pull request that connects them.
  • The pull direction, controller to config repo, not pipeline to cluster.
  • Each environment with the version it runs, so promotion is visible.
  • Sync settings: auto-sync, prune, self-heal.

The deployment strategies diagram shows how the rollout itself can be canary or blue-green, the CI/CD pipeline diagram covers the build stages in detail, the Kubernetes architecture diagram shows the cluster itself, and the Kubernetes YAML to diagram post shows how to turn the config repo's manifests into a picture.

Build it in Archboard

  1. Sign in with Google or GitHub and create a diagram.
  2. Add a Person from the C4 Model pack, two Repository nodes and a Pipeline from the DevOps pack, and a Registry from the Docker pack.
  3. Add a Frame from the Core pack for the cluster, with a Container for the GitOps controller.
  4. Add two Namespace nodes from the Kubernetes pack with a Deployment in each, labeled with the version it runs.
  5. Draw the pull as a dashed edge from the controller to the config repo, and add a Markdown block from the Core pack with the workflow rules.

The example uses 12 diagram nodes, within the Free plan.

FAQ

What is the difference between GitOps and CI/CD? CI/CD builds, tests and delivers software. GitOps is a way to do the delivery part: the desired state lives in Git and an agent in the target environment pulls and reconciles it, instead of a pipeline pushing changes in.

Should I use Argo CD or Flux? Both implement the same model. Argo CD has a rich web UI and application-centric views; Flux is a set of composable controllers that many teams drive entirely through Git and the CLI.

Do I need separate app and config repositories? It is a common convention, not a rule. Separate repos keep deployment history clean and let config change without rebuilding code.

How do I roll back with GitOps? Revert the commit that changed the version in the config repo. The controller applies the previous state.

How are secrets handled in GitOps? Store them encrypted in Git, or store references in Git and let an operator fetch the values from a secrets manager inside the cluster.

Start free — one seat, no credit card.

Related posts

← Back to blog

Open a canvas in a minute

Sign in with Google or GitHub. Free for a single seat. Upgrade when the team joins.