infrastructure/nixos/common/modules/vault.nix

122 lines
3.2 KiB
Nix
Raw Normal View History

2023-04-28 15:55:06 +02:00
{ config, pkgs, lib, flat_hosts, inputs, ... }:
2022-09-29 18:56:03 +02:00
with lib;
let
cfg = config.services.v.vault;
hostIP = config.deployment.targetHost;
vault_hosts =
filter ({ tags ? [ ], ip ? "", ... }: (elem "vault" tags) && (ip != hostIP))
flat_hosts;
cluster_config = concatStrings (map ({ ip, ... }: ''
retry_join {
leader_api_addr = "http://${ip}:${toString cfg.port}"
}
'') vault_hosts);
in {
options.services.v.vault = {
2023-04-28 16:05:49 +02:00
enable = mkEnableOption "v's vault";
2022-09-29 18:56:03 +02:00
node_id = mkOption {
type = types.str;
2023-04-28 16:05:49 +02:00
description = lib.mdDoc ''
2022-09-29 18:56:03 +02:00
The cluster node id of this node
'';
};
openFirewall = mkOption {
type = types.bool;
default = false;
2023-04-28 16:05:49 +02:00
description = lib.mdDoc ''
Whether to open port `port` and `clusterPort` in the firewall for vault
2022-09-29 18:56:03 +02:00
'';
};
port = mkOption {
type = types.int;
default = 8200;
2023-04-28 16:05:49 +02:00
description = lib.mdDoc ''
2022-09-29 18:56:03 +02:00
The port vault listens on
**note:** this has to be the same for all nodes in a cluster
'';
};
clusterPort = mkOption {
type = types.int;
default = 8201;
2023-04-28 16:05:49 +02:00
description = lib.mdDoc ''
2022-09-29 18:56:03 +02:00
The cluster port vault listens on
**note:** this has to be the same for all nodes in a cluster
'';
};
2023-04-28 15:55:06 +02:00
autoUnseal = mkOption {
type = types.bool;
default = false;
2023-04-28 16:05:49 +02:00
description = lib.mdDoc ''
Whether to auto-unseal this vault
2023-04-28 15:55:06 +02:00
'';
};
2023-04-28 16:05:49 +02:00
autoUnsealKeysFile = mkOption {
2023-04-28 15:55:06 +02:00
type = types.str;
default = null;
example = "/var/lib/vault-unseal/keys.json";
2023-04-28 16:05:49 +02:00
description = lib.mdDoc ''
auto unseal keys to use, has to be a json file with the following structure
```json
{
keys = [ key_1, ..., key_n ]
}
```
2023-04-28 15:55:06 +02:00
'';
};
2022-09-29 18:56:03 +02:00
};
config = mkIf cfg.enable {
2023-04-28 15:55:06 +02:00
assertions = [{
2023-04-28 16:05:49 +02:00
assertion = cfg.autoUnseal -> (cfg.autoUnsealKeysFile != null);
2023-04-28 15:55:06 +02:00
message = "If autoUnseal is enabled, a token path is required!";
}];
2022-09-29 18:56:03 +02:00
networking.firewall.allowedTCPPorts =
mkIf cfg.openFirewall [ cfg.port cfg.clusterPort ];
services.vault = {
enable = true;
# bin version includes the UI
package = pkgs.vault-bin;
address = "0.0.0.0:${toString cfg.port}";
storageBackend = "raft";
storagePath = "/var/lib/vault-raft";
storageConfig = ''
node_id = "${cfg.node_id}"
'' + cluster_config;
extraConfig = ''
ui = true
disable_mlock = true
api_addr = "http://${hostIP}:${toString cfg.port}"
cluster_addr = "http://${hostIP}:${toString cfg.clusterPort}"
'';
};
2023-04-28 15:55:06 +02:00
systemd.services.vault-unseal = mkIf cfg.autoUnseal {
description = "Vault unseal service";
wantedBy = [ "multi-user.target" ];
after = [ "vault.service" ];
environment = {
VAULT_ADDR = "http://localhost:${toString cfg.port}";
2023-04-28 16:05:49 +02:00
VAULT_KEY_FILE = cfg.autoUnsealKeysFile;
2023-04-28 15:55:06 +02:00
};
serviceConfig = {
User = "vault";
Group = "vault";
Type = "simple";
Restart = "on-failure";
ExecStart = "${
inputs.vault-unseal.packages.${pkgs.system}.default
}/bin/vault-unseal";
};
};
2022-09-29 18:56:03 +02:00
};
}