Kvindo™ Cloud Docs


Language

Kafka Cluster

A Kafka Cluster is a managed Apache Kafka deployment running in KRaft mode — the modern consensus design where Kafka itself elects a leader from a dedicated set of controller nodes, with no ZooKeeper ensemble to operate. Each node runs on its own dedicated VM, and the cluster is described as one resource: spec.brokers and spec.controllers each hold one entry per node, listing only its name and subnet.

Key concepts

• Two roles, sized independently — brokers hold your data, controllers hold only cluster metadata. Sizing is one offer triplet per role (brokerVmOfferId/brokerVolumeOfferId/brokerVolumeSizeGiB and the controller* equivalents) rather than per node, so a role's nodes are interchangeable by design and a heterogeneous role simply cannot be described

• Controllers: exactly 1 or 3 — the KRaft quorum needs an odd voter count. 1 is a documented non-HA tier that can later be grown to 3; shrinking a controller set is rejected

• Brokers: 1..N, grow-only — a modify may add one broker at a time. Kafka has no shrink operation, so removing a broker is rejected outright instead of being silently ignored

• Node name is the real identity — the server resolves each entry against this cluster's existing members by name and reuses the same node (and its VM) when it matches. Renaming is treated as removing the old node and adding a new one, deliberately, so don't rename a node you want to keep

• A NAT floating IP is required to create a cluster — every node installs Java at bootstrap, and controllers are never given a floating IP of their own, so they need outbound internet through the VPC's NAT. This is a create-time precondition, not a runtime caveat

• No cluster-wide credential on this resource — the internal admin SCRAM credential is generated and stored server-side only; create a Kafka User to get a real, tenant-facing password

• Public access is TLS-only — private by default. Setting spec.createPublicIpv4 adds the TLS listener on port 9096 advertised on a floating IP; the plaintext listener stays bound to the private network, so a public cluster is never reachable without TLS

Parameters
UI Name API / kc name Terraform name Optional Format Default Is read only Description
Brokers spec.brokers spec.brokers No list of objects — No One entry per broker — 1..N, grow-only
Broker name brokers[].name brokers[].name No string — No The real identity — reuse across modifies to keep an existing broker; renaming is treated as remove-and-add
Broker subnet brokers[].vpcSubnetId brokers[].vpc_subnet_id No ULID — references a VPC Subnet — No Subnet for this broker's VM
Controllers spec.controllers spec.controllers No list of objects — No Exactly 1 or 3 — the KRaft quorum needs an odd voter count
Controller name controllers[].name controllers[].name No string — No Same identity rule as brokers: renaming replaces the node
Controller subnet controllers[].vpcSubnetId controllers[].vpc_subnet_id No ULID — references a VPC Subnet — No Subnet for this controller's VM
Parameters set spec.parametersSetId spec.parameters_set_id Yes ULID — references a KafkaParametersSet — No Broker-level properties applied to the whole cluster; swapping which set is referenced is allowed freely on a modify
Kafka version spec.kafkaVersion spec.kafka_version No string — Kafka version 4.3.1 No Must be a version the deployed image prefetched — the platform installs Kafka only from the tarball it ships. Immutable in v1: there is no rolling upgrade
Broker VM offer spec.brokerVmOfferId spec.broker_vm_offer_id No string (≤32) — compute offer — No Applies to every broker. Resolved and written back server-side when omitted; see the Console catalog for real offer ids (e.g. g3-2c4-100)
Broker volume offer spec.brokerVolumeOfferId spec.broker_volume_offer_id No string (≤32) — disk offer — No Applies to every broker (e.g. gp3-750)
Broker volume size spec.brokerVolumeSizeGiB spec.broker_volume_size_gib No integer — GiB — No Applies to every broker
Controller VM offer spec.controllerVmOfferId spec.controller_vm_offer_id No string (≤32) — compute offer g3-1c1-100 No Applies to every controller — a controller only serves metadata, so it is sized far smaller than a broker
Controller volume offer spec.controllerVolumeOfferId spec.controller_volume_offer_id No string (≤32) — disk offer gp3-750 No Applies to every controller
Controller volume size spec.controllerVolumeSizeGiB spec.controller_volume_size_gib No integer — GiB 10 No Applies to every controller
Use FQDN spec.useFqdn spec.use_fqdn Yes boolean false No Advertise DNS names instead of raw IPs, so a node's address can change without every client re-seeding. Immutable after creation
Public IPv4 spec.createPublicIpv4 spec.create_public_ipv4 Yes boolean false No Adds the TLS listener (port 9096) on a floating IP. Immutable after creation
Cluster id status.clusterId status.cluster_id — string — Yes The Kafka cluster id — stable for the cluster's lifetime
CA certificate status.caCertificate status.ca_certificate — string (PEM) — Yes The public half of the cluster CA — a client needs it as its truststore to reach the TLS listeners. Credential-free
Bootstrap (plaintext) status.bootstrapServersPlaintext status.bootstrap_servers_plaintext — list of strings — Yes host:9092 for every broker — private addresses only, always populated even on a public cluster
Bootstrap (TLS) status.bootstrapServersTls status.bootstrap_servers_tls — list of strings — Yes host:9093 — SASL_SSL over the private network
Bootstrap (public) status.bootstrapServersPublic status.bootstrap_servers_public — list of strings — Yes host:9096 — SASL_SSL over the floating IP; empty unless spec.createPublicIpv4
DNS seed FQDN status.dnsSeedFqdn status.dns_seed_fqdn — string — Yes Set only when spec.useFqdn is enabled
Cluster state status.clusterState status.cluster_state — string — Yes One of ok, degraded, no-quorum, or null when unknown
Active controllers status.activeControllerCount status.active_controller_count — integer — Yes How many controllers are currently voters in the metadata quorum
Quorum leader status.quorumLeaderNodeId status.quorum_leader_node_id — integer — Yes KRaft node.id of the current metadata-quorum leader
Under-replicated status.underReplicatedPartitions status.under_replicated_partitions — integer — Yes Partitions with fewer in-sync replicas than their replication factor
Offline partitions status.offlinePartitions status.offline_partitions — integer — Yes Partitions with no leader at all — non-zero means an outage for those topics
Unexpected topics status.unexpectedTopics status.unexpected_topics — list of strings — Yes Topics that exist on the cluster but were never declared through the API. Reported, never deleted — a Streams/Debezium app whose internal topic was refused must surface, not vanish
Anti-affinity OK status.antiAffinityOk status.anti_affinity_ok — boolean — Yes False when two nodes that should be separate share a VM (degraded placement)
Anti-affinity message status.antiAffinityMessage status.anti_affinity_message — string — Yes Human-readable detail behind antiAffinityOk
Brokers status.brokers status.brokers — list of objects — Yes Observed state per broker
Broker node id brokers[].nodeId brokers[].node_id — integer — Yes The KRaft node.id the platform assigned — stable for the VM's lifetime, never reissued
Broker observed state brokers[].observedState brokers[].observed_state — string — Yes One of active, fenced, unregistered, unknown
Broker leaders brokers[].leaderPartitionCount brokers[].leader_partition_count — integer — Yes How many partition leaders this broker currently hosts
Controllers status.controllers status.controllers — list of objects — Yes Observed state per controller
Quorum leader? controllers[].isQuorumLeader controllers[].is_quorum_leader — boolean — Yes True for the controller currently leading the metadata quorum
Controller lag controllers[].lagOffsets controllers[].lag_offsets — integer — Yes How far this controller trails the leader
Examples

A single-broker, single-controller cluster — the smallest tier that is real, and a legitimate dev/cost starting point before growing to 3 controllers.

Terraform

Python SDK

kc CLI


Related pages

Resource docs

Examples

An unhandled error has occurred. Reload 🗙