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