How to Migrate Kafka to Redpanda Across Every Repo in Your Org
Mandy Singh
July 17, 2026 · // 13 min read
Migrating from Kafka to Redpanda across an organization is mostly an infrastructure-as-code problem, not an application-rewrite problem. Because Redpanda is Kafka API compatible, most producers and consumers connect without code changes. The work lives in the IaC and config layer: bootstrap server endpoints, Terraform modules, Helm values, SASL and TLS settings, and monitoring config, scattered across every repo that references the cluster. Connecting a client to Redpanda takes little work. The volume is in finding and updating every reference to the old cluster across the codebase.
Redpanda runs the Kafka protocol without a JVM and without ZooKeeper, which is why teams move to it: lower latency, less operational weight, one binary instead of a broker plus a coordination service. Kafka clients from version 0.11 onward are compatible, and most workloads reuse the same client libraries they already run.
That compatibility is also what makes the migration easy to underscope. A producer can connect, publish, and look healthy while an alert rule, a transactional consumer, or a Terraform module three repos over is still pointed at the old cluster or the old metric names. The method below covers the mechanical IaC edits every repo needs, the exactly-once and monitoring checks that a connectivity test does not cover, and how to run both across dozens of repos.
What does a Kafka to Redpanda IaC migration actually involve?
The work splits into two layers: mechanical edits and a compatibility audit.
Layer one is mechanical. Bootstrap server endpoints change. Cluster-provisioning resources change. ZooKeeper resources come out. JVM heap tuning comes out. Shared modules that provision Kafka users, topics, and ACLs get repointed. Prometheus scrape jobs and Grafana dashboards move to Redpanda’s native metrics. Each of these is a find-and-replace with a known target, repo by repo.
Layer two is the compatibility audit. A few Kafka behaviors that are on by default do not carry over automatically, and a few config surfaces behave differently on Redpanda. These changes pass a basic produce-and-consume test and then break a specific workload later. A migration can pass connectivity and smoke tests with these still unaddressed.
Both layers have to run on every affected repo. Skipping the audit is what turns a completed-looking migration into a production incident weeks later.
The mechanical fix list
Run this across every repo in scope.
| Kafka pattern | Redpanda replacement |
|---|---|
bootstrap_servers = ["broker.msk.amazonaws.com:9092"] | Redpanda broker endpoints (Cloud or self-hosted) |
provider "kafka" { bootstrap_servers = [...] } (Mongey) | Same provider, new endpoints, plus a pinned kafka_version |
aws_msk_cluster / confluent_kafka_cluster resource | redpanda_cluster (redpanda-data provider) or a Redpanda Helm release |
ZooKeeper nodes, subcharts, and aws_msk broker/ZK wiring | Removed. Redpanda uses Raft, not ZooKeeper |
KAFKA_HEAP_OPTS, -Xmx, JMX exporter sidecars | Removed. Redpanda has no JVM |
module "x" { source = ".../kafka-user" } | source = ".../redpanda-user" |
Prometheus job scraping kafka_exporter / JMX | Redpanda native metrics at /public_metrics |
Alert rules and dashboards on kafka_server_* metric names | Redpanda metric names (redpanda_*) |
sasl.mechanism with multiple SCRAM mechanisms per user | A single SCRAM mechanism per user |
One detail carries most of the mechanical volume: the Mongey kafka Terraform provider works against Redpanda, so existing kafka_topic and kafka_acl definitions can point at the new cluster largely unchanged. Redpanda does not implement every Kafka Metadata API, so the provider needs an explicit kafka_version pinned at initialization. Teams that manage clusters through the redpanda-data provider have a heavier change, because redpanda_cluster, redpanda_topic, redpanda_user, and redpanda_acl replace the MSK or Confluent resource types entirely.
The transactions and monitoring audit
Run two checks on every repo before calling it migrated: exactly-once semantics and monitoring. Neither is covered by a connectivity test.
First, the exactly-once flags. Kafka enables idempotence and transactions by default. Redpanda requires them to be set explicitly, with redpanda.enable_transactions=true and redpanda.enable_idempotence=true in the cluster config. A transactional producer or an exactly-once consumer group will connect fine, publish fine in a smoke test, and then fail the first time it opens a transaction against a cluster where the flag was never set. Nothing in the connection or the smoke test flags it.
Second, the monitoring rename. Every Prometheus rule, Grafana panel, and alert that references a Kafka JMX metric name is dead the moment the exporter goes away. Redpanda exposes its own metrics under different names. An alert that silently evaluates to nothing gives no warning, so consumer lag on the new cluster can climb unmonitored until someone checks it by hand.
Search for these surfaces:
rg "enable_transactions|enable_idempotence" --type tf --type yaml
rg "kafka_server_|kafka_exporter|jmx" -g "*.yml" -g "*.yaml" -g "*.json"
rg "kafka-user|bootstrap_servers|zookeeper" --type tf
Every match is a migration task. Some are mechanical repointing. Others, like a dashboard built around JMX metric names or a service that relies on a Kafka feature added after protocol version 3.1, need a human to decide the correct replacement. Flag those for review rather than auto-rewriting them.
Here’s a prompt you can run today
If you are already running AI-assisted code changes, this is the prompt to hand it, repo by repo:
Migrate this repository's Kafka infrastructure references to Redpanda.
For each repository:
1. Repoint connection config to the Redpanda cluster:
- bootstrap_servers in Terraform, Helm values, and app config
- SASL mechanism set to a single SCRAM mechanism (SCRAM-SHA-512)
- TLS settings updated to the Redpanda CA and endpoints
2. Update infrastructure-as-code:
- Replace aws_msk_cluster / confluent_kafka_cluster with redpanda_cluster
or a Redpanda Helm release, depending on how this repo provisions
- For the Mongey kafka provider, keep kafka_topic and kafka_acl resources
but pin kafka_version explicitly
- Update module sources from kafka-user to redpanda-user
- Remove ZooKeeper resources and JVM heap tuning (KAFKA_HEAP_OPTS, -Xmx)
3. Update observability:
- Repoint Prometheus scrape jobs to Redpanda's /public_metrics endpoint
- Rewrite alert rules and dashboards that reference kafka_server_* metrics
to Redpanda metric names
4. Audit exactly-once semantics:
- If this repo runs a transactional producer or exactly-once consumer,
confirm enable_transactions and enable_idempotence are set on the cluster
config, and flag for review if the setting is ambiguous
5. Do not modify producer or consumer logic that already works over the
Kafka API. Flag any use of a Kafka feature added after protocol version 3.1.
That prompt handles one repo. The scale problem is the other forty that reference the same cluster, each with its own Terraform state, its own dashboards, and its own owning team.
Why the mechanical fixes aren’t the hard part
One repo is straightforward work. The difficulty comes from the same cluster being referenced by dozens of services across many teams.
Each repo has its own connection config, and the endpoint is buried in a different place in each: a Terraform variable in one, a Helm value in another, a hardcoded string in a third. Each repo has its own monitoring, so the metric-rename work is different in every dashboard. Each repo has its own owner, which means each change needs a review, a PR, an approval, and a merge from a different person on a different sprint.
The cutover itself, moving the actual data and traffic from the old brokers to Redpanda, is a separate operations exercise with its own tooling. What the IaC migration governs is every repo that names the cluster. If half of them still point at the old bootstrap servers after cutover, the cutover is not done. Updating those references is the slow part, and it is usually tracked in a spreadsheet that falls out of date as teams work at different paces.
Platform teams usually inherit these migrations, and the reference update is why they drag. The Kafka API compatibility removed the code-rewrite blocker. The coordination across teams and repos is what remains, and it does not automate itself just because each individual edit is small.
Running the migration across every repo at once
The change is defined. The mechanical fix list and the audit above cover what goes into each repo. For most teams the hard part is executing that change consistently across every repository that references the cluster, and tracking it to completion without a spreadsheet.
Tidra is an AI coding agent for both implementation and coordination of code changes across your organization. For an IaC migration like this one, that means:
- Target every repo that references the cluster with one filter. Scope the initiative once to every repository that still names the old bootstrap servers or calls the
kafka-usermodule, and skip the manual repo-by-repo hunt. - Run the same instructions across all of them. The mechanical fix list and the transactions-and-monitoring audit become the initiative’s plan. Tidra generates the change for each repo individually, respecting that repo’s own Terraform layout, Helm values, and dashboards.
- Review the plan before any code moves. Nothing gets touched until you have seen what Tidra proposes for each repo and confirmed it. Where a repo provisions its own cluster rather than consuming a shared one, or uses a Kafka feature that needs manual handling, you adjust the plan there.
- Bulk-create pull requests. Each repo gets its own reviewable PR, opened for the team that owns it. Your engineers review and merge, the same as any other change.
- Track completion from one dashboard instead of a spreadsheet. Open, merged, blocked, per repo, in one place.
Tidra does not replace the judgment calls in the audit. Deciding the correct Redpanda metric name for a bespoke dashboard, or confirming a transactional workload’s semantics, still needs a human. What changes is that the forty repos stop being forty separate side projects competing for attention and become one initiative with a single owner and a visible status.
“The ability to iterate on the plan before touching any code changes everything,” is how one platform engineer described running a coordinated infrastructure change this way rather than by hand.
Before and after: what the diff looks like
A Terraform diff for a service that consumes the shared cluster:
--- kafka.tf
+++ kafka.tf
@@
provider "kafka" {
- bootstrap_servers = ["b-1.prod-msk.abc123.kafka.us-east-1.amazonaws.com:9096"]
+ bootstrap_servers = ["seed-abc.redpanda.cloud:9092"]
+ kafka_version = "3.1.0" # pin: Redpanda does not implement all Metadata APIs
}
-module "service_user" {
- source = "git::ssh://[email protected]/org/tf-modules//kafka-user"
+module "service_user" {
+ source = "git::ssh://[email protected]/org/tf-modules//redpanda-user"
name = "orders-consumer"
}
resource "kafka_topic" "orders" {
name = "orders"
replication_factor = 3
partitions = 12
}
And a monitoring diff:
--- alerts.yaml
+++ alerts.yaml
@@
- alert: ConsumerLagHigh
- expr: kafka_consumergroup_lag > 10000
+ expr: redpanda_kafka_consumer_group_lag_sum > 10000
for: 5m
That is one repo. At forty repos, it is forty PRs shaped like this, each generated against that repo’s actual config, each opened for the team that owns it to review.
Kafka to Redpanda migration checklist
Use this as a per-repo gate before you call a repo migrated:
bootstrap_serversrepointed in every Terraform, Helm, and app config location- Cluster-provisioning resources replaced (
redpanda_clusteror Redpanda Helm release) where the repo owns provisioning - ZooKeeper resources and JVM heap tuning removed
kafka-usermodule sources updated toredpanda-user- SASL reduced to a single SCRAM mechanism per user, TLS repointed to the Redpanda CA
kafka_versionpinned where the Mongey provider manages topics and ACLs- Prometheus scrape jobs repointed to Redpanda’s metrics endpoint
- Alert rules and dashboards migrated off Kafka JMX metric names
enable_transactionsandenable_idempotenceconfirmed on the cluster config for any transactional or exactly-once workload- Full integration test run against Redpanda, beyond a basic connectivity check
What usually breaks after a Kafka to Redpanda migration ships
Almost always the same set of things:
A transactional producer that never got the flags. The migration passed CI, connectivity worked, a smoke test published fine. Then a job that opens a transaction runs for the first time against a cluster where enable_transactions was never set, and it fails. This is the failure the audit exists to catch before merge instead of after deploy.
An alert that stopped firing. A Prometheus rule still references a Kafka JMX metric name that no longer exists, so it silently evaluates to nothing. Consumer lag climbs on the new cluster and no page goes out. Migrate the rules with the endpoints, not after.
A user with two SASL credentials. Redpanda does not support a single user holding multiple SCRAM mechanisms at once. A service that authenticated with SCRAM-SHA-256 in one place and SCRAM-SHA-512 in another needs consolidating to one.
Dangling ZooKeeper and JMX infrastructure. Redpanda needs neither, so any ZooKeeper nodes, JMX exporters, or JVM tuning left in the IaC keep running and keep costing money. Because nothing breaks when it is left in place, the cleanup is easy to skip while it keeps billing.
A client on a post-3.1 Kafka feature. Redpanda is compatible with Kafka clients from 0.11 on, but a workload built around a Metadata API behavior or a feature added after protocol version 3.1 may behave differently. Validate the specific Kafka surfaces each workload uses, not compatibility in the abstract.
FAQ
Is Redpanda compatible with Kafka? Redpanda is compatible with Apache Kafka clients from version 0.11 onward, using the same wire protocol. Most producers and consumers reuse their existing client libraries without code changes. Compatibility is per-surface, so validate the specific APIs, security settings, and Schema Registry behavior each workload depends on rather than treating compatibility as a single yes or no.
Do I need to change application code to migrate from Kafka to Redpanda? Usually not. Because Redpanda speaks the Kafka API, the migration is mostly an infrastructure-as-code and config change: bootstrap server endpoints, authentication, Terraform and Helm definitions, and monitoring. Application logic that already works over the Kafka API generally keeps working.
Does Redpanda need ZooKeeper? No. Redpanda uses the Raft consensus protocol internally and runs as a single binary with no JVM and no ZooKeeper. Any ZooKeeper resources in your existing Kafka IaC should be removed as part of the migration.
What breaks when migrating Kafka to Redpanda? The most common issues: transactions and idempotence must be enabled explicitly on Redpanda because Kafka enables them by default; monitoring rules that reference Kafka JMX metric names stop firing; a single user cannot hold multiple SCRAM mechanisms at once; and leftover ZooKeeper or JVM infrastructure keeps billing. Workloads using Kafka features added after protocol version 3.1 need individual validation.
Can a Kafka to Redpanda migration be automated? The IaC and config edits automate well: endpoint repointing, module source swaps, ZooKeeper and JVM removal, and metric-name rewrites are all pattern-based. The exactly-once semantics review and the runtime data cutover need human judgment. The right split is to automate the reference updates across every repo and keep the semantic decisions under review.
How do you migrate Kafka to Redpanda across many repos at once? Define the IaC fix list and the transactions-and-monitoring audit once, then run them as a single initiative scoped to every repo that references the cluster. Each repo gets its own generated change and its own pull request, reviewed by the team that owns it, tracked from one place instead of a spreadsheet per team.
Connect your Git provider and Tidra opens pull requests in every repo that still references your Kafka cluster: tidra.ai/get-started/