Run the SXCHNGE production Vault as a three-node raft cluster: two nodes on exch (the SXCHNGE prod server) and one on infra-gamma. It is the first production component: Mongo, NATS and the applications get their secrets and dynamic Mongo credentials from it, so it has to exist and survive the loss of one server before anything else is deployed. Losing infra-gamma keeps the majority on exch; losing one node on exch keeps two of three.
Approach
Deployment code in this repository under infra/prod/, deployed by this repository's CI later (separate task); the first rollout is run by hand from the same files. Plain Docker Compose on each server, no Swarm: one Compose project on exch with two Vault services, one on infra-gamma with the third.
Raft integrated storage, retry_join between the three nodes. Each node publishes its API and cluster ports on the server's private address only (exch 192.168.10.191, infra-gamma 192.168.10.98); the two nodes on exch use different host ports. No internal TLS on the private network: raft cluster traffic on the cluster port is already encrypted by Vault itself.
Auto-unseal with the transit seal on the platform Vault (https://vault.sendico.io): a dedicated transit key and a policy that allows only encrypt/decrypt with that key, and a periodic orphan token for the SXCHNGE Vault. Recovery keys from vault operator init are kept by people, never on the servers or in the repository.
Image: the latest stable hashicorp/vault release, digest resolved at deploy time and recorded in the deploy output, as the repository rules require; nothing generated is committed.
Applications on exch reach Vault through one Docker network alias shared by the two local nodes.
Rollout: create the transit key and policy on the platform Vault, start the three nodes, vault operator init with recovery keys, then restart each node in turn and check that it unseals by itself and the raft index matches.
Out of scope here (separate tasks): KV/AppRole/policies and the Mongo database plugin, Mongo and NATS clusters, CI deployment, raft snapshots to SILO, monitoring and alerts.
Acceptance criteria
vault operator raft list-peers shows three voters: two on exch, one on infra-gamma.
After docker restart of any single node it unseals without a person and rejoins with the same raft committed index.
Stopping the infra-gamma node leaves the cluster writable from exch; starting it again rejoins it.
Vault ports listen only on the private addresses; nothing is reachable from the internet.
The transit token can only encrypt/decrypt with its own key on the platform Vault.
Recovery keys and the root token are not stored on any server, in the repository or in CI; the root token is revoked after bootstrap.
infra/prod/ documents the layout, ports, the rollout and how to replace a node.
Notes
Placement follows the agreed target scheme (SXCHNGE Vault 2 on exch + 1 on infra-gamma, the same rule as Vault/Mongo/NATS elsewhere: the majority where the consumers run).
Dependency on the platform Vault: if it is unreachable while a node restarts, that node stays sealed until the platform Vault is back or the node is unsealed with the recovery keys. Running nodes are not affected.
Firewall (OpenStack security groups, owned by the lead): exch <-> infra-gamma on the Vault cluster port; exch -> vault.sendico.io 443. To request before the rollout.
The public entry point and the domain for SXCHNGE are still being decided; Vault does not need them.
Mongo dynamic credentials (database/creds/*, 1 h TTL) make Vault availability a hard dependency of the applications; this is why it is deployed 2+1 first.
### Goal
Run the SXCHNGE production Vault as a three-node raft cluster: two nodes on `exch` (the SXCHNGE prod server) and one on `infra-gamma`. It is the first production component: Mongo, NATS and the applications get their secrets and dynamic Mongo credentials from it, so it has to exist and survive the loss of one server before anything else is deployed. Losing `infra-gamma` keeps the majority on `exch`; losing one node on `exch` keeps two of three.
### Approach
1. Deployment code in this repository under `infra/prod/`, deployed by this repository's CI later (separate task); the first rollout is run by hand from the same files. Plain Docker Compose on each server, no Swarm: one Compose project on `exch` with two Vault services, one on `infra-gamma` with the third.
2. Raft integrated storage, `retry_join` between the three nodes. Each node publishes its API and cluster ports on the server's private address only (exch 192.168.10.191, infra-gamma 192.168.10.98); the two nodes on `exch` use different host ports. No internal TLS on the private network: raft cluster traffic on the cluster port is already encrypted by Vault itself.
3. Auto-unseal with the `transit` seal on the platform Vault (`https://vault.sendico.io`): a dedicated transit key and a policy that allows only `encrypt`/`decrypt` with that key, and a periodic orphan token for the SXCHNGE Vault. Recovery keys from `vault operator init` are kept by people, never on the servers or in the repository.
4. Image: the latest stable `hashicorp/vault` release, digest resolved at deploy time and recorded in the deploy output, as the repository rules require; nothing generated is committed.
5. Applications on `exch` reach Vault through one Docker network alias shared by the two local nodes.
6. Rollout: create the transit key and policy on the platform Vault, start the three nodes, `vault operator init` with recovery keys, then restart each node in turn and check that it unseals by itself and the raft index matches.
Out of scope here (separate tasks): KV/AppRole/policies and the Mongo database plugin, Mongo and NATS clusters, CI deployment, raft snapshots to SILO, monitoring and alerts.
### Acceptance criteria
- [ ] `vault operator raft list-peers` shows three voters: two on `exch`, one on `infra-gamma`.
- [ ] After `docker restart` of any single node it unseals without a person and rejoins with the same raft committed index.
- [ ] Stopping the `infra-gamma` node leaves the cluster writable from `exch`; starting it again rejoins it.
- [ ] Vault ports listen only on the private addresses; nothing is reachable from the internet.
- [ ] The transit token can only encrypt/decrypt with its own key on the platform Vault.
- [ ] Recovery keys and the root token are not stored on any server, in the repository or in CI; the root token is revoked after bootstrap.
- [ ] `infra/prod/` documents the layout, ports, the rollout and how to replace a node.
### Notes
- Placement follows the agreed target scheme (SXCHNGE Vault 2 on exch + 1 on infra-gamma, the same rule as Vault/Mongo/NATS elsewhere: the majority where the consumers run).
- Dependency on the platform Vault: if it is unreachable while a node restarts, that node stays sealed until the platform Vault is back or the node is unsealed with the recovery keys. Running nodes are not affected.
- Firewall (OpenStack security groups, owned by the lead): exch <-> infra-gamma on the Vault cluster port; exch -> vault.sendico.io 443. To request before the rollout.
- The public entry point and the domain for SXCHNGE are still being decided; Vault does not need them.
- Mongo dynamic credentials (`database/creds/*`, 1 h TTL) make Vault availability a hard dependency of the applications; this is why it is deployed 2+1 first.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Goal
Run the SXCHNGE production Vault as a three-node raft cluster: two nodes on
exch(the SXCHNGE prod server) and one oninfra-gamma. It is the first production component: Mongo, NATS and the applications get their secrets and dynamic Mongo credentials from it, so it has to exist and survive the loss of one server before anything else is deployed. Losinginfra-gammakeeps the majority onexch; losing one node onexchkeeps two of three.Approach
infra/prod/, deployed by this repository's CI later (separate task); the first rollout is run by hand from the same files. Plain Docker Compose on each server, no Swarm: one Compose project onexchwith two Vault services, one oninfra-gammawith the third.retry_joinbetween the three nodes. Each node publishes its API and cluster ports on the server's private address only (exch 192.168.10.191, infra-gamma 192.168.10.98); the two nodes onexchuse different host ports. No internal TLS on the private network: raft cluster traffic on the cluster port is already encrypted by Vault itself.transitseal on the platform Vault (https://vault.sendico.io): a dedicated transit key and a policy that allows onlyencrypt/decryptwith that key, and a periodic orphan token for the SXCHNGE Vault. Recovery keys fromvault operator initare kept by people, never on the servers or in the repository.hashicorp/vaultrelease, digest resolved at deploy time and recorded in the deploy output, as the repository rules require; nothing generated is committed.exchreach Vault through one Docker network alias shared by the two local nodes.vault operator initwith recovery keys, then restart each node in turn and check that it unseals by itself and the raft index matches.Out of scope here (separate tasks): KV/AppRole/policies and the Mongo database plugin, Mongo and NATS clusters, CI deployment, raft snapshots to SILO, monitoring and alerts.
Acceptance criteria
vault operator raft list-peersshows three voters: two onexch, one oninfra-gamma.docker restartof any single node it unseals without a person and rejoins with the same raft committed index.infra-gammanode leaves the cluster writable fromexch; starting it again rejoins it.infra/prod/documents the layout, ports, the rollout and how to replace a node.Notes
database/creds/*, 1 h TTL) make Vault availability a hard dependency of the applications; this is why it is deployed 2+1 first.