at 18.09-beta 4.9 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.vault; 7 8 configFile = pkgs.writeText "vault.hcl" '' 9 listener "tcp" { 10 address = "${cfg.address}" 11 ${if (cfg.tlsCertFile == null || cfg.tlsKeyFile == null) then '' 12 tls_disable = "true" 13 '' else '' 14 tls_cert_file = "${cfg.tlsCertFile}" 15 tls_key_file = "${cfg.tlsKeyFile}" 16 ''} 17 ${cfg.listenerExtraConfig} 18 } 19 storage "${cfg.storageBackend}" { 20 ${optionalString (cfg.storagePath != null) ''path = "${cfg.storagePath}"''} 21 ${optionalString (cfg.storageConfig != null) cfg.storageConfig} 22 } 23 ${optionalString (cfg.telemetryConfig != "") '' 24 telemetry { 25 ${cfg.telemetryConfig} 26 } 27 ''} 28 ${cfg.extraConfig} 29 ''; 30in 31 32{ 33 options = { 34 services.vault = { 35 enable = mkEnableOption "Vault daemon"; 36 37 package = mkOption { 38 type = types.package; 39 default = pkgs.vault; 40 defaultText = "pkgs.vault"; 41 description = "This option specifies the vault package to use."; 42 }; 43 44 address = mkOption { 45 type = types.str; 46 default = "127.0.0.1:8200"; 47 description = "The name of the ip interface to listen to"; 48 }; 49 50 tlsCertFile = mkOption { 51 type = types.nullOr types.str; 52 default = null; 53 example = "/path/to/your/cert.pem"; 54 description = "TLS certificate file. TLS will be disabled unless this option is set"; 55 }; 56 57 tlsKeyFile = mkOption { 58 type = types.nullOr types.str; 59 default = null; 60 example = "/path/to/your/key.pem"; 61 description = "TLS private key file. TLS will be disabled unless this option is set"; 62 }; 63 64 listenerExtraConfig = mkOption { 65 type = types.lines; 66 default = '' 67 tls_min_version = "tls12" 68 ''; 69 description = "Extra text appended to the listener section."; 70 }; 71 72 storageBackend = mkOption { 73 type = types.enum [ "inmem" "file" "consul" "zookeeper" "s3" "azure" "dynamodb" "etcd" "mssql" "mysql" "postgresql" "swift" "gcs" ]; 74 default = "inmem"; 75 description = "The name of the type of storage backend"; 76 }; 77 78 storagePath = mkOption { 79 type = types.nullOr types.path; 80 default = if cfg.storageBackend == "file" then "/var/lib/vault" else null; 81 description = "Data directory for file backend"; 82 }; 83 84 storageConfig = mkOption { 85 type = types.nullOr types.lines; 86 default = null; 87 description = "Storage configuration"; 88 }; 89 90 telemetryConfig = mkOption { 91 type = types.lines; 92 default = ""; 93 description = "Telemetry configuration"; 94 }; 95 96 extraConfig = mkOption { 97 type = types.lines; 98 default = ""; 99 description = "Extra text appended to <filename>vault.hcl</filename>."; 100 }; 101 }; 102 }; 103 104 config = mkIf cfg.enable { 105 assertions = [ 106 { assertion = cfg.storageBackend == "inmem" -> (cfg.storagePath == null && cfg.storageConfig == null); 107 message = ''The "inmem" storage expects no services.vault.storagePath nor services.vault.storageConfig''; 108 } 109 { assertion = (cfg.storageBackend == "file" -> (cfg.storagePath != null && cfg.storageConfig == null)) && (cfg.storagePath != null -> cfg.storageBackend == "file"); 110 message = ''You must set services.vault.storagePath only when using the "file" backend''; 111 } 112 ]; 113 114 users.users.vault = { 115 name = "vault"; 116 group = "vault"; 117 uid = config.ids.uids.vault; 118 description = "Vault daemon user"; 119 }; 120 users.groups.vault.gid = config.ids.gids.vault; 121 122 systemd.services.vault = { 123 description = "Vault server daemon"; 124 125 wantedBy = ["multi-user.target"]; 126 after = [ "network.target" ] 127 ++ optional (config.services.consul.enable && cfg.storageBackend == "consul") "consul.service"; 128 129 restartIfChanged = false; # do not restart on "nixos-rebuild switch". It would seal the storage and disrupt the clients. 130 131 preStart = optionalString (cfg.storagePath != null) '' 132 install -d -m0700 -o vault -g vault "${cfg.storagePath}" 133 ''; 134 135 serviceConfig = { 136 User = "vault"; 137 Group = "vault"; 138 PermissionsStartOnly = true; 139 ExecStart = "${cfg.package}/bin/vault server -config ${configFile}"; 140 PrivateDevices = true; 141 PrivateTmp = true; 142 ProtectSystem = "full"; 143 ProtectHome = "read-only"; 144 AmbientCapabilities = "cap_ipc_lock"; 145 NoNewPrivileges = true; 146 KillSignal = "SIGINT"; 147 TimeoutStopSec = "30s"; 148 Restart = "on-failure"; 149 StartLimitInterval = "60s"; 150 StartLimitBurst = 3; 151 }; 152 153 unitConfig.RequiresMountsFor = optional (cfg.storagePath != null) cfg.storagePath; 154 }; 155 }; 156 157}