Overview
etcd is a strongly consistent key-value store used as the coordination layer for leader election, distributed locking, and service configuration. This template deploys a single stretched etcd cluster with exactly one member per Control Plane location, sharing one raft quorum across regions, with raft timers tuned for cross-region round trips and auto-compaction enabled. It is also the consensus store used by thepostgres-multi-location template, and is independently useful as a cross-region coordination store for your own services.
This template creates a new GVC and requires at least 2 locations. For a single-location cluster, use the etcd template instead.
What Gets Created
- GVC — A new GVC pinned to the configured locations via static placement. The GVC is what pins the deployment’s locations, so it is always created.
- Stateful etcd Workload — (
RELEASE_NAME-etcd): one member in each configured location, usingreplicaDirectaddressing so every member is individually reachable. Client API on2379, raft peer traffic on2380. - Volume Set — (
RELEASE_NAME-etcd-vs): persistent storage per member at/var/lib/etcdfor the raft write-ahead log and snapshots. ext4, general-purpose-ssd, final snapshot on delete, 7-day snapshot retention. - Secret — (
RELEASE_NAME-etcd-startup): an opaque startup script that computes each member’s name, peer URL, and the full cluster list at container start from the location it is running in. - Identity & Policy — An identity bound to the workload with
revealaccess to the startup script secret and nothing else.
replica-0.RELEASE_NAME-etcd.LOCATION.GVC_NAME.cpln.local:2380). There is no operator, no discovery service, and no join step — every member receives the full cluster list up front and they elect a leader among themselves.
Installation
This template has no external prerequisites. To install, follow the instructions for your preferred method:UI
Browse, install, and manage templates visually
CLI
Manage templates from your terminal
Terraform
Declare templates in your Terraform configurations
Pulumi
Declare templates in your Pulumi programs
Configuration
The defaultvalues.yaml for this template:
Locations and Quorum
global.gvc.name— Name of the GVC this template creates. It must not name a GVC that already exists.global.gvc.locations— The member map: one etcd member is deployed in each listed location. At least 2 locations are required.
With N locations you survive
floor((N-1)/2) losses, so an even count never buys anything over the odd count below it. Two locations is permitted as a deliberate warm-standby topology, but it survives nothing automatically.
The global.gvc block lives under global so that a parent chart — postgres-multi-location consumes this template as a subchart — sets the GVC and location list once and Helm propagates it. Each location runs exactly one member; any other replica count fails at render time.
Changing
global.gvc.locations reprovisions the cluster: every member restarts with a new cluster list. This is not etcd’s graceful member add / member remove path, so plan it as a maintenance window.Image and Resources
image— The etcd image to run (etcd 3.6.5).resources.cpu/resources.memory— CPU and memory allocated to each member (default:500m,512Mi).
Raft Tuning
tuning.heartbeatIntervalMs— Leader heartbeat interval, roughly 0.5–1.5× the worst round trip between your locations.tuning.electionTimeoutMs— How long a follower waits before campaigning. Must be at least 10× the heartbeat interval, and at most50000. Both bounds are enforced at render time.
Storage
volumeset.capacity— Persistent volume size in GiB per member for the raft write-ahead log and snapshots (minimum 10).
dbSize plateaus instead of dropping — only etcdctl defrag returns space to the filesystem.
Internal Access
TheinternalAccess section controls which workloads can reach the client API on 2379. Cross-location traffic inside one GVC is same-GVC traffic, so the default covers a stretched cluster with no extra rule.
Firewall changes take up to roughly two and a half minutes to take effect. Re-test after waiting rather than concluding the setting was ignored.
Connecting to etcd
Point clients at one endpoint per location so they can fail over. From inside the cluster:
RELEASE_NAME-etcd-LOCATION, so member list maps one-to-one onto your location list.
Allow about two minutes of convergence after a cold install before concluding that a member is unreachable — cross-region service discovery can lag a workload reporting ready by well over a minute.
Ports
Failover Behavior
Measured on a three-location cluster (aws-us-east-1, aws-eu-central-1, aws-us-west-2) with the default 5 s election timeout:
Write latency is bounded by one cross-region round trip, because the leader needs a follower acknowledgement before it can commit. Measured with the leader in
aws-eu-central-1:
A client co-located with the leader does not get local-write latency — one cross-region round trip is the floor for any stretched quorum.
Upgrades
Nothing serializes the restart: the field that would limit it (rolloutOptions.maxUnavailableReplicas) is not retained by the platform, so the chart deliberately does not set it. Running more members per location has not been tested and should not be assumed to help.
Behavior Under Quorum Loss
When a majority of members is unreachable, the cluster stops committing writes. What that looks like from a client is easy to misread:- Writes hang rather than failing fast. They block until they time out, so always give clients a short
--command-timeout(or the client-library equivalent) — otherwise connections pile up against a cluster that cannot commit. - Serializable reads keep succeeding against stale data. A read issued with
--consistency=sis served from the local member’s own store and never notices the loss of quorum. IS LEADER: trueis not proof of leadership. An isolated survivor keeps reporting itself as leader for about 6 seconds while unable to commit anything. Health-check with a linearizable read (etcdctl get KEY, without--consistency=s), never withendpoint status.
Recovering from a Lost Location
recovery.forceNewClusterInLocation is for the case where quorum is permanently gone — with two locations, that is the loss of either one. It is not needed for a location that is coming back: a member that returns with its volume intact rejoins on its own in well under a minute.
1
Confirm the loss is permanent
etcdctl member remove cannot help here, because removing a member itself requires quorum.2
Force a new single-member cluster
Set
recovery.forceNewClusterInLocation to the surviving location’s name and upgrade the release. That member restarts as a single-member cluster rebuilt from its own write-ahead log and serves writes again immediately.3
Clear the setting
Set
recovery.forceNewClusterInLocation back to "" and upgrade again. Leaving it set means the flag fires on every future restart of that member.4
Reset the lost location's volume before it rejoins
The evicted members still hold the old cluster ID and refuse to start until their data directory is cleared. Uninstall and reinstall, or delete that volume, so the member bootstraps fresh.
External References
etcd Documentation
Official etcd documentation
Tuning for Latency
Heartbeat and election timeout guidance for cross-region clusters
Disaster Recovery
Recovering an etcd cluster that has lost quorum
etcd Multi-Location Template
View the source files, default values, and chart definition