Monedula

monedula-gitops v1.0.0, AGPL-3.0

GitOps for Apache Kafka

Describe topics, access, quotas, schemas, SCRAM users and Confluent RBAC as YAML in Git. monedula-gitops diffs it against the live cluster, applies only what changed, and fails CI when the cluster drifts. The same manifests run from a CLI or a Kubernetes operator.

Homebrew
brew install monedula-dev/tap/monedula-gitops
Go
go install github.com/monedula-dev/monedula-gitops/cmd/monedula-gitops@latest
Docker
docker run --rm ghcr.io/monedula-dev/monedula-gitops:latest --help
Helm (operator)
helm install monedula-gitops oci://ghcr.io/monedula-dev/charts/monedula-gitops
manifests/orders.yaml
apiVersion: gitops.monedula.dev/v1alpha1
kind: KafkaTopic
metadata:
  name: orders
spec:
  clusterRef: { name: prod }
  topicName: orders
  partitions: 6
  config:
    retention.ms: "604800000"
  access:
    producers:
      - principal: User:svc-checkout
    consumers:
      - principal: User:svc-fraud
        group: fraud-orders
terminal
monedula-gitops diff -f ./manifests --cluster-config-file ./cluster.yaml# preview: the topic, plus the ACLs its access block compiles tomonedula-gitops apply -f ./manifests --cluster-config-file ./cluster.yamlmonedula-gitops verify -f ./manifests --cluster-config-file ./cluster.yaml# exit 0: no drift. exit 1: drift, and the CI job fails.

The problem

Kafka configuration rarely lives in one place.

Topics come from one script, ACLs from another, schemas from application pipelines, quotas from an administrator, and Confluent RBAC role bindings from yet another tool. Over time only the live cluster describes the system, and nobody has reviewed that description.

6
resource kinds, from topics to Confluent RBAC role bindings
8
broker images tested in CI: Apache Kafka 3.9 to 4.3, Confluent Platform 7.6 to 8.3
25
runnable scenarios in the repository, each checked end to end

How it works

  1. 01

    Import import cluster

    Turn a live cluster into manifests.

  2. 02

    Declare YAML + pull request

    Topics, access, quotas, schemas, SCRAM users and role bindings as Kubernetes-style YAML.

  3. 03

    Diff diff

    diff and apply --dry-run show the plan against the live cluster first.

  4. 04

    Apply apply

    Only the needed operations run. Pruning and risky changes wait for explicit flags.

  5. 05

    Verify verify

    verify exits 1 on drift, so a scheduled CI job catches out-of-band changes.

  1. Git repository manifests/*.yaml, reviewed in pull requests
  2. CLI in CI validate, diff, apply, verify
    Operator in Kubernetes CRDs, admission webhooks, reconcile loop
  3. Kafka topics, ACLs, quotas, SCRAM users
    Schema Registry and MDS schemas, Confluent RBAC role bindings
The manifests in Git drive the CLI in CI and the operator in Kubernetes, which change Kafka, Schema Registry and MDS.

A topic and its access, in one manifest

Most Kafka tooling keeps a topic in one place and its access in another. monedula-gitops attaches access to the topic itself: list the producers and consumers, and the matching topic and consumer-group ACLs are generated. On RBAC-backed clusters the same block can compile to Confluent MDS role bindings.

When you need prefixed patterns, shared consumer groups or host restrictions, standalone KafkaAccessPolicy and KafkaRoleBinding resources are there.

Strimzi
KafkaTopic + KafkaUser
Confluent for Kubernetes
topic + separate role-binding resources
Jikkou
topic + separate principal resources
Terraform
one resource per ACL
monedula-gitops
one KafkaTopic with an access block

Import an existing cluster

import cluster reads topics, ACLs, quotas, schemas and, where supported, RBAC role bindings, and writes manifests. Verifying them against the same cluster reports no drift.

How to import a cluster

terminal
monedula-gitops import cluster --cluster-config-file ./clusters/prod.yaml --output-dir ./imported
monedula-gitops verify -f ./imported -R --cluster-config-file ./clusters/prod.yaml   # exits 0: no drift

SCRAM users and Confluent RBAC role bindings

A KafkaUser declares a SCRAM credential, so the topic, its access and the principal that uses it live in Git together. The CLI reads the password from an environment variable or a file; the operator reads it from a Kubernetes Secret, or generates one.

KafkaRoleBinding manages Confluent MDS role bindings alongside ACLs.

manifests/svc-checkout.yaml
apiVersion: gitops.monedula.dev/v1alpha1
kind: KafkaUser
metadata:
  name: svc-checkout
spec:
  clusterRef: { name: prod }
  password:
    valueFrom: { env: SVC_CHECKOUT_PASSWORD }

Nothing is deleted by accident

--dry-run previews every change. The CLI never deletes a topic, SCRAM user or quota that you remove from Git. --prune deletes only ACLs and role bindings that fall inside a grant your manifests still declare, and risky changes such as a partition increase, a lower schema compatibility or a removed quota limit wait for --allow-destructive. In Kubernetes, a topic's deletion policy decides whether deleting the resource also deletes the topic, and Delete also needs the allow-delete annotation.

Safety gates

Exit codes
0Success, or no drift for verify
1Drift detected (verify)
2Validation, configuration or connectivity error, or a failed operation
3Only gated operations remain: they await --allow-destructive

Install

Homebrew
brew install monedula-dev/tap/monedula-gitops
Go
go install github.com/monedula-dev/monedula-gitops/cmd/monedula-gitops@latest
Docker
docker run --rm ghcr.io/monedula-dev/monedula-gitops:latest --help
Helm (operator)
helm install monedula-gitops oci://ghcr.io/monedula-dev/charts/monedula-gitops

Prebuilt binaries for Linux and macOS are on the releases page. Next: get started with the CLI.

Questions

Is monedula-gitops free, and can I use it at work?
Yes. It is AGPL-3.0 with no paid edition, and using it on your own clusters, as a CLI or as an operator in your own infrastructure, does not oblige you to share your code or manifests: AGPL obligations apply when you distribute it, modified or not, or let others use a modified version over a network. For commercial licensing, contact us.
Does it work with Confluent Platform and Confluent Cloud?
Apache Kafka and Confluent Platform are fully supported, including Schema Registry and, on Confluent Platform, MDS role bindings. Confluent Cloud is validated for topics, ACLs, schemas and import; Cloud does not expose the quota and SCRAM APIs. See supported platforms for the tested versions.
How is it different from Jikkou?
Both manage Kafka as code. monedula-gitops declares access on the topic itself, runs as a Kubernetes operator that reconciles continuously as well as a CLI, and manages Confluent Platform role bindings through MDS. Jikkou runs as a CLI or an API server and covers more platforms and resource types, such as Kafka Connect connectors and Confluent Cloud role bindings. The comparison page lists the details, with the date they were checked.

Support

Help from the people who build it

We can help you run monedula-gitops across a large estate, from design to day-to-day operations.

Part of
Monedula Flock

More free tools for Apache Kafka from the same team. About Flock

Go, AGPL-3.0, v0.10.0

monedula-acl-rbac-converter

A CLI that converts Apache Kafka ACLs into Confluent RBAC role bindings through a checksummed plan and verifies effective access before any ACL is deleted.

Go, Apache-2.0, v0.11.0

monedula-sim-link

A read-only Go CLI that turns a real Kafka cluster into a shareable Kafka Simulator link, with an MCP server for AI agents.

Free, runs in your browser

Kafka Simulator

An interactive, deterministic Apache Kafka simulator in the browser: break a cluster, scrub the timeline and read why it reacted.