Kvindo™ Cloud Docs
An Etcd Cluster is a managed distributed key-value store for service discovery, coordination, and configuration storage. Each instance runs on its own dedicated VM; the cluster is described as a single resource with one entry per node in spec.instances — there is no separate node-group resource.
• Cluster-wide sizing, per-instance identity — spec.vmOfferId/spec.volumeOfferId/spec.volumeSizeGiB apply identically to every instance (the cluster is homogeneous by design); only each instance's id and subnet (spec.instances[].id/vpcSubnetId) vary per node
• Instance id is caller-supplied — the platform diffs the desired instances array against the current one on every modify; reuse an instance's existing id to keep it, or supply a new id to add a node
• Scaling moves one step between valid sizes — a single request may only move the instance count to the adjacent allowed size (1↔3, 3↔5, 5↔7), and cannot add and remove instances in the same request (submit two separate modifies instead). To go from 1 node to 5, apply two separate modify requests: 1→3, then 3→5
• Subnet placement — every instance must share one Vpc (etcd peers across different VPCs cannot reach each other); an existing instance's vpcSubnetId is immutable — to move an instance to a different subnet, add a new instance there and remove the old one
• Cluster size — must be odd and between 1 and 7 (etcd needs a raft quorum to stay available, so an even count tolerates no more failures than the next-lower odd one, and 7 is etcd's own documented practical ceiling); any other count is rejected with a validation error
• Public access — private by default; set spec.createPublicIpv4 to give every instance a public IPv4. Immutable after creation
• Monitoring addons are opt-in — spec.addons is empty by default and nothing extra runs on a node until you name an addon. Today one is offered: node_exporter 1.12.1 on port 9100, bound to each node's private address and reachable only from inside the cluster's VPC. It carries no authentication, so it is never exposed on the public address even on a cluster with createPublicIpv4. Removing it from the list is a real instruction: the process is stopped and its binary deleted
• Provisioning needs no outbound internet — the etcd release, the TLS tooling and the addon binaries all ship in the platform's provisioning image, and Ansible itself is pushed to each node from it. A cluster in a VPC with no NAT and no floating IP provisions exactly like any other; an existing cluster picks this up on its next modify
| UI Name | API / kc name | Terraform name | Optional | Format | Default | Is read only | Description |
|---|---|---|---|---|---|---|---|
| Tier | spec.tier |
spec.tier |
No | string | standard |
No | Reserved for future use — only standard is accepted today |
| Etcd version | spec.etcdVersion |
spec.etcd_version |
No | string — etcd version | 3.6.14 |
No | 3.6.14 is currently the only supported version — any other value is rejected on both create and modify, so this field is effectively immutable for now |
| Root password | spec.rootPassword |
spec.root_password |
No | string (sensitive) — 8-64 chars, letters/digits/./_/- only |
— | No | Cluster-wide credential for etcdctl auth. Returned in plain text as spec.rootPassword on every read - treat API/CLI output as sensitive |
| Public IPv4 | spec.createPublicIpv4 |
spec.create_public_ipv4 |
Yes | boolean | false |
No | Give every instance a public IPv4 |
| VM offer | spec.vmOfferId |
spec.vm_offer_id |
No | string (≤32) — compute offer | g3-1c1-100 |
No | Applies to every instance — see the Console catalog |
| Volume offer | spec.volumeOfferId |
spec.volume_offer_id |
No | string (≤32) — disk offer | gp3-750 |
No | Applies to every instance |
| Volume size | spec.volumeSizeGiB |
spec.volume_size_gib |
No | integer — GiB | 10 |
No | Applies to every instance |
| Instances | spec.instances |
spec.instances |
No | list of objects | — | No | One entry per cluster node |
| Instance ID | instances[].id |
instances[].id |
No | ULID | — | No | Caller-supplied — reuse across modifies to keep an existing instance |
| VPC subnet | instances[].vpcSubnetId |
instances[].vpc_subnet_id |
No | ULID — references a VPC Subnet | — | No | Subnet for this instance |
| Addons | spec.addons |
spec.addons |
No | list of objects | empty | No | Optional Prometheus sidecars. Empty means none installed — an empty list on a modify also REMOVES any addon installed earlier |
| Addon name | addons[].name |
addons[].name |
No | string — node_exporter |
— | No | The only addon offered today; any other name is rejected |
| Addon version | addons[].version |
addons[].version |
No | string — X.Y.Z, must be one the image carries | — | No | node_exporter: 1.12.1. Required rather than defaulted — an addon without a version has not said which build to run |
| CA certificate | status.caCert |
status.ca_cert |
— | string | — | Yes | Cluster's public CA certificate — pass to etcdctl --cacert to trust the cluster's TLS |
| Port | status.port |
status.port |
— | integer | — | Yes | Port etcdctl connects to — always 2379 today |
| Instances | status.instances |
status.instances |
— | list of objects | — | Yes | The provisioned cluster nodes |
| Instance ID | instances[].id |
instances[].id |
— | ULID | — | Yes | Matches the spec instance id |
| Public IPv4 | instances[].publicIpV4 |
instances[].public_ipv4 |
— | string | — | Yes | Set only when the cluster has public IPv4 enabled |
| Private IPv4 | instances[].privateIpV4 |
instances[].private_ipv4 |
— | string | — | Yes | Address on the instance's VPC subnet |
| Addons | status.addons |
status.addons |
— | list of strings — name@version |
— | Yes | The addons actually INSTALLED, not the requested ones — the two differ while a change is in flight. An addon that failed to start does not appear |
| Node exporter endpoints | status.nodeExporterEndpoints |
status.node_exporter_endpoints |
— | list of strings — host:9100 |
— | Yes | One per node, PRIVATE addresses. Empty unless the node_exporter addon is applied — this is what a Prometheus scrape config points at |
A private 3-node cluster on an existing subnet.
Terraform
Python SDK
kc CLI
Resource docs
Examples