{"id":854,"date":"2026-10-19T03:15:00","date_gmt":"2026-10-19T03:15:00","guid":{"rendered":"https:\/\/bestpilotsnow.com\/blog\/?p=854"},"modified":"2026-10-19T03:15:00","modified_gmt":"2026-10-19T03:15:00","slug":"gitops-deploy-readiness-audit","status":"publish","type":"post","link":"https:\/\/bestpilotsnow.com\/blog\/gitops-deploy-readiness-audit\/","title":{"rendered":"The GitOps Preflight: A Readiness Audit for Your Deploys"},"content":{"rendered":"<p>Preflight is not a ritual. It is a structured hunt for the handful of faults that ruin flights, run in the same order every time, because order is what catches omissions. Deployments deserve the same treatment, and GitOps \u2014 the operating model that records how a platform should be configured, keeps that record versioned, and lets an automated controller enforce it \u2014 is the machine that makes such a hunt worthwhile. What follows is a readiness audit in three parts. Run it against any team that claims to &#8220;do GitOps,&#8221; including your own, and count the honest answers. A team that clears all of it has earned the label. A team that clears half has a folder of YAML and a wish.<\/p>\n<h2>Run This Audit Before You Call It GitOps<\/h2>\n<p>Ground rule first: the audit inspects outcomes, not tool names. Argo CD or Flux installed does not mean the model is operating, and the cheapest failure in this space is a reconciliation tool running in a mode where nobody lets it reconcile. Keep that in mind as you work through the checks \u2014 several of them will catch installations that exist in name only.<\/p>\n<h2>Part One: The Paperwork<\/h2>\n<p>These five checks cover what is written, where it lives, and whether the writing can be trusted.<\/p>\n<ul>\n<li><strong>Check 1 \u2014 The intended state is written, not remembered.<\/strong> Pick any production component at random. Can a team member produce the document that describes its correct configuration in under a minute? If the answer lives in someone&#8217;s head or a stale wiki page, the audit stops here.<\/li>\n<li><strong>Check 2 \u2014 Every change entered through review.<\/strong> Sample the last ten production changes. Each should trace to an approved proposal in the repository \u2014 a pull request with a reviewer&#8217;s name on it. Console sessions and hand-edits are disqualifying, however well intentioned.<\/li>\n<li><strong>Check 3 \u2014 References are pinned.<\/strong> Scan the manifests for moving targets: container tags reading <em>:latest<\/em>, charts floating on &#8220;current,&#8221; remote bases pointed at a branch head. Mutable references quietly break the guarantee that what was tested is what runs. Digests and locked versions pass; anything else fails.<\/li>\n<li><strong>Check 4 \u2014 Environments are directories, not branches.<\/strong> Long-lived environment branches breed merge conflicts that reviewers stop reading. Side-by-side directories with promoted changes keep the diffs reviewable. Branch-per-environment is the marker of a layout chosen in a hurry.<\/li>\n<li><strong>Check 5 \u2014 The rendered output is what got reviewed.<\/strong> Templates hide changes. Ask whether reviewers see the final rendered difference \u2014 the actual objects that will change \u2014 or an abstract template diff they must mentally compile. The second option is where surprises hatch.<\/li>\n<\/ul>\n<h2>Part Two: The Keys<\/h2>\n<p>Direction of trust decides whether the model is safe, so the next checks read like a security walk-around.<\/p>\n<ul>\n<li><strong>Check 6 \u2014 Production pulls; nothing outside pushes.<\/strong> In a pull model, the credentials that can modify production stay inside production, and the controller outside needs nothing beyond read access to one repository path. Guidance for service-based systems (NIST SP 800-204C is the usual citation) treats push-based delivery \u2014 where the build system holds production keys and fires them at the cluster \u2014 as structurally insecure. If the delivery pipeline carries cluster credentials, note it; that item outweighs everything else on this list.<\/li>\n<li><strong>Check 7 \u2014 The controller&#8217;s own permissions are narrow.<\/strong> Reconcilers tend to install with sweeping rights, often cluster-wide administration. Look for scoped-down configuration: restricted projects, impersonated service accounts, vendor lockdown flags. A guardian with the keys to everything is a liability wearing a uniform.<\/li>\n<li><strong>Check 8 \u2014 Write access to the watched path equals deploy access, and is treated that way.<\/strong> Whoever can push to the monitored directory can ship code \u2014 including bots and AI assistants. Verify each account and token with write access is named, justified, and reviewed like a deployer, because that is exactly what it is.<\/li>\n<li><strong>Check 9 \u2014 Credentials never sit in the repository.<\/strong> Secrets should arrive encrypted or not at all: SOPS with age keys, Sealed Secrets, or an External Secrets Operator syncing from a vault. Plain secrets in Git are an immediate fail, and so is a &#8220;temporary&#8221; exception older than a month.<\/li>\n<li><strong>Check 10 \u2014 Webhook endpoints are not open doors.<\/strong> A webhook only makes the controller pull sooner; the polling loop still exists underneath (Argo CD polls on the order of every two minutes, with jitter). But an unauthenticated webhook endpoint without rate limiting is an invitation, so confirm a shared secret is set.<\/li>\n<\/ul>\n<h2>Part Three: Deletion Guards \u2014 Where GitOps Eats Data<\/h2>\n<p>The scariest failure in this model is not a bad deploy. It is an accidental removal. A merge conflict drops a file from the production directory; the controller, faithfully keeping reality aligned with the record, deletes the live object \u2014 a database namespace, a persistent volume claim \u2014 and the storage goes with it. Any honest audit spends its sharpest questions here. Confirm four protections exist and have been tested:<\/p>\n<ul>\n<li>Stateful, hard-to-recreate resources (namespaces holding data, PVCs, CRDs) are shielded from automated pruning.<\/li>\n<li>Volume reclaim policies retain storage after deletion rather than releasing it.<\/li>\n<li>A CI gate flags any proposed change that removes those resource types, before a human can merge it in a hurry.<\/li>\n<li>Someone can describe, from memory, the recovery drill \u2014 and the drill has actually been run.<\/li>\n<\/ul>\n<h2>The Six-Step Recovery Runbook, Rehearsed<\/h2>\n<p>When the pruning accident happens anyway \u2014 and given merge conflicts, it eventually will \u2014 the difference between a bad afternoon and a lost quarter is whether a written recovery sequence exists. The canonical runbook has six movements, and the audit should verify each is documented and current:<\/p>\n<ol>\n<li>Stop the controller from reconciling the affected scope, so the wound stops widening while you work.<\/li>\n<li>Establish what was lost and when, using application history, cluster events, and the repository log.<\/li>\n<li>Restore the deleted declarations the proper way \u2014 a revert proposal through review, not another console session.<\/li>\n<li>Bring the data back from backup, once the objects exist to receive it.<\/li>\n<li>Resume reconciliation and watch the first full pass like a hawk.<\/li>\n<li>Close the gap that allowed it: the pruning guard, the deletion check, the reclaim policy.<\/li>\n<\/ol>\n<p>One subtlety belongs in the runbook&#8217;s first step. On Flux, suspending a resource survives independently of the repository; on Argo CD, a naive pause can be undone by parent objects re-applying their children, so the suspension must be made in a way the automation itself will not reverse. A runbook that gets this wrong freezes nothing and calls it frozen. Practical monitoring chops make the difference between noticing a stalled reconciliation and discovering it in the morning \u2014 teams without that skill set can start with <a href=\"https:\/\/bestpilotsnow.com\/blog\/master-monitoring-your-guide-to-the-prometheus-with-grafana-course\/\">a course path covering Prometheus with Grafana<\/a>, and broaden their platform fundamentals through <a href=\"https:\/\/bestpilotsnow.com\/blog\/devops-training-in-delhi-fast-track-your-it-career-with-hands-on-learning\/\">hands-on DevOps training in Delhi<\/a> or similar structured programs.<\/p>\n<h2>Scoring the Walk-Around<\/h2>\n<p>Grade the audit the way a flight instructor would: unsatisfactory, incomplete, satisfactory. Anything under a full pass on Part Two is a no-go despite whatever the demos show, because credential direction is the foundation everything else rests on. Part Three failures are deferred maintenance on a live volcano \u2014 the model works beautifully right up to the day it faithfully deletes the thing you forgot to guard. The full statement of the model these checks skim \u2014 principles, tooling, and the reasoning behind each \u2014 is laid out in <a href=\"https:\/\/www.xopsschool.com\/gitops\/\">this detailed GitOps guide<\/a> from xOps School, and reading it after the audit will answer most of the &#8220;why&#8221; questions the checklist raises.<\/p>\n<p>Attitude toward checklists is the real test, in the air and in operations. The pilot who preflights from memory is the one who misses the tow-hook still attached; the team that &#8220;knows their setup is fine&#8221; is the one that meets the pruning accident unwritten. Run the walk-around. Write down what fails. Fix the failures in reviewable, reversible steps. That loop \u2014 inspect honestly, record plainly, correct deliberately \u2014 is the same muscle aviation has trained for a century, and <a href=\"https:\/\/bestpilotsnow.com\/blog\/light-aircraft-maintenance-mistakes-to-avoid-a-practical-guide-for-aircraft-owners\/\">the maintenance mistakes light aircraft owners make<\/a> read like a preview of the configuration mistakes every operations team makes before someone finally hands them a checklist.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A ten-point preflight-style audit for GitOps: paperwork, credentials, deletion guards and the six-step recovery runbook, scored like a checkride.<\/p>\n","protected":false},"author":6,"featured_media":855,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[669],"tags":[],"class_list":["post-854","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aviation"],"_links":{"self":[{"href":"https:\/\/bestpilotsnow.com\/blog\/wp-json\/wp\/v2\/posts\/854","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bestpilotsnow.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bestpilotsnow.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bestpilotsnow.com\/blog\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/bestpilotsnow.com\/blog\/wp-json\/wp\/v2\/comments?post=854"}],"version-history":[{"count":1,"href":"https:\/\/bestpilotsnow.com\/blog\/wp-json\/wp\/v2\/posts\/854\/revisions"}],"predecessor-version":[{"id":865,"href":"https:\/\/bestpilotsnow.com\/blog\/wp-json\/wp\/v2\/posts\/854\/revisions\/865"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/bestpilotsnow.com\/blog\/wp-json\/wp\/v2\/media\/855"}],"wp:attachment":[{"href":"https:\/\/bestpilotsnow.com\/blog\/wp-json\/wp\/v2\/media?parent=854"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bestpilotsnow.com\/blog\/wp-json\/wp\/v2\/categories?post=854"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bestpilotsnow.com\/blog\/wp-json\/wp\/v2\/tags?post=854"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}