<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Kopf on ferkakta.dev</title><link>https://ferkakta.dev/tags/kopf/</link><description>Recent content in Kopf on ferkakta.dev</description><generator>Hugo</generator><language>en-US</language><copyright>Copyright fizz.</copyright><lastBuildDate>Fri, 20 Feb 2026 12:00:00 -0500</lastBuildDate><atom:link href="https://ferkakta.dev/tags/kopf/index.xml" rel="self" type="application/rss+xml"/><item><title>Making a Kopf operator idempotent: three-layer existence checks and the redisReady race</title><link>https://ferkakta.dev/kopf-operator-idempotency-three-layer-check/</link><pubDate>Fri, 20 Feb 2026 12:00:00 -0500</pubDate><guid>https://ferkakta.dev/kopf-operator-idempotency-three-layer-check/</guid><description>&lt;p&gt;Our tenant operator provisions databases, cache users, and credentials for each tenant in a multi-tenant SaaS platform. PostgreSQL roles on shared RDS, ElastiCache RBAC users, SSM parameters with generated passwords. It worked exactly once per tenant. The second time it ran, it regenerated every password and overwrote every SSM parameter. Running services holding the old credentials immediately lost their database and cache connections.&lt;/p&gt;
&lt;p&gt;This was the blocker for auto-deploy.&lt;/p&gt;
&lt;h2 id="every-deploy-was-a-coordinated-outage"&gt;Every deploy was a coordinated outage&lt;/h2&gt;
&lt;p&gt;The orchestrator runs &lt;code&gt;terraform apply&lt;/code&gt; for each tenant on every deploy. Terraform reconciles the Tenant CRD, which fires Kopf&amp;rsquo;s &lt;code&gt;on_tenant_create&lt;/code&gt; handler. The handler doesn&amp;rsquo;t distinguish between &amp;ldquo;new tenant&amp;rdquo; and &amp;ldquo;existing tenant whose CRD was re-applied.&amp;rdquo; It generates fresh passwords, creates new PostgreSQL roles (which fail because the role exists, or worse, succeed and orphan the old one), and overwrites SSM parameters with credentials that no running pod knows about.&lt;/p&gt;</description></item></channel></rss>