Deployment Examples¶
Reference deployments of the FermiHDI stack for Ansible, Chef, Puppet, Kubernetes (raw manifests and Helm) and Nomad. Each subdirectory has its own README.
| Example | Directory |
|---|---|
| Ansible | ansible_example/ |
| Chef | chef_example/ |
| Puppet | puppet_example/ |
| Kubernetes | k8s_example/ |
| Nomad | nomad_example/ |
All of these assume DMS-managed nodes¶
Every example configures the Storage Cluster Controller and Storage Nodes with
identity only — DMS URL, node name, bootstrap token, certificate material and
the per-plane subnets. None sets RECORD_SIZE, SCC_IP, MASTER_CPUSET or a
storage device address, and that is correct for this deployment mode: the DMS
delivers record size, the SCC address, storage devices and the hash election
while each node's data plane waits at its boot gate.
A node reporting DP_HOLDING under these examples is waiting for the DMS, not
misconfigured. If it never releases, investigate the DMS side.
For a pre-provisioned or standalone deployment — no DMS config pushes — those settings become required and the node exits without them. See the per-component configuration guides:
hd_scc/docs/configuration_guide.mdhd_sn/docs/configuration_guide.mdhd_proxy/docs/configuration_guide.mdhd_dms/docs/configuration_guide.md
Two things to check before adapting these¶
1. Telemetry export is not configured. The examples set FERMIHDI_OTEL_URL,
which is a routing probe used to pick the node's observability IP — it configures
no exporter. The OpenTelemetry SDK reads OTEL_EXPORTER_OTLP_ENDPOINT and
OTEL_EXPORTER_OTLP_PROTOCOL, and neither appears in any example. Add them if you
expect traces and metrics to leave the node.
2. The gRPC ports are not declared. Beyond the documented 6986 / 6987 / 8080, the cluster uses three derived gRPC listeners:
| Port | Served by | Dialled by |
|---|---|---|
6996 |
SCC — BatchHashVerification | every SN |
6997 |
SCC — query dispatch | HD Proxy |
6997 |
SN — query dispatch (production port + 10) | SCC |
No example declares them in a containerPort, Service or Nomad port block.
Within a flat pod or host network this is cosmetic, since the traffic is direct
peer-to-peer. It stops being cosmetic the moment you add a default-deny
NetworkPolicy, a service mesh or a host firewall — the existing NetworkPolicies
in the Kubernetes example cover only node→DMS traffic on 6985/6986/6989, so
adding cluster-wide isolation without these three ports silently breaks batch
verification and query fan-out.
That failure is quiet by design elsewhere in the stack: gRPC's BuildAndStart()
does not fail when a listener cannot bind, and a blocked verification stream
presents as batches that never get confirmed rather than as a connection error.
Also note: FERMIHDI_FORCE_POSIX is set on the SCC and SN in several examples.
Neither binary reads it — it is a client-side switch in hd_sdk. Leave it on
ingester and proxy containers; it is inert on the storage components.
Verified against hd_scc@c915937, hd_sn@fea7c61, hd_proxy@2888e6c and
hd_dms@6311f08 on 2026-08-18.