Skip to content

Two configuration documents

A node runs from two documents. The node file configures one process: where it listens, which raft cluster it belongs to, which identity providers it trusts, where its admin door is, and where the second document is. The deployment document states what the deployment is: providers, credentials, budgets, profiles, access rules, guardrails. The first is read by one process and nobody else. The second is what every node agrees on, and the cluster stores it.

The node file holds every key that names a fact about one machine. A listener address, a data directory, a certificate path, a socket. It holds deployment, the path of the second document, relative to itself. A deployment key in the node file is refused at load, with the key named and the other document pointed at.

The deployment document holds every key the cluster stores. A path never appears in it. A credential is a reference, ${secret:NAME}, that each node resolves for itself, and a model is a content-addressed manifest each node materializes. The document has to make sense on a node that did not write it, and a path does not.

A node file with no deployment key is a node whose deployment arrives through the API. A clustered node starts that way and waits to be told what it is. A node without a cluster refuses, since nothing could tell it later.

The two halves have two lifecycles. The node file is parsed at start and on reload, by this process, and it is never stored. The deployment document seeds a stored source, named default, the first time a cluster starts with nothing stored. After that the store is what is served, and the document is that source’s one writer: a start applies it when its version says it is newer, and a reload applies it whether or not it says so.

One writer is the rule every source lives under. The operator writes its sources, the Terraform provider writes its own, and the API refuses a write to a source whose last writer is somebody else’s tool. The deployment document is held to the same rule. A write to default through the API or the console is refused with the file named, because the next reload would erase it. The refusal replaces an edit that disappeared without a word.

One file carrying both halves made that rule impossible to state. An operator editing it could not tell which keys were this node’s and which were the deployment’s until something else wrote the source. Two files make the split a fact of the filesystem rather than a table in a reference page.

The Helm charts render both files into one ConfigMap. config is the node file, minus the keys the chart writes itself, and deployment is the deployment document, stamped with the release revision as its version so an edit lands when the pods roll. A deployment key under config fails at render time with the place it belongs.

On a fleet of machines the deployment document is the same bytes on every host and the node file differs per host in its cluster block. The first host to start seeds the cluster. See Run the front door on VMs.

A tool that needs only the deployment half takes either file. A guardrails evaluation and a rule suite read the deployment document directly, or follow a node file’s deployment to it. The gateway and pistra check take the node file, and pistra check names both files it read.

A document from before the split, with both halves in one file, is refused with the misplaced keys named. Move those keys into a second file and name it with deployment.