{ config, lib, ... }: let cfg = config.bagel.services.vault; inherit (lib) mkEnableOption mkOption mkIf concatStringsSep types; mkPeerNode = fqdn: '' retry_join { leader_api_addr = "https://${fqdn}" leader_tls_servername = "${fqdn}" } ''; wanAddress = if config.bagel.infra.self.wan.family == "inet6" then "[${config.bagel.infra.self.wan.address}]" else "${config.bagel.infra.self.wan.address}"; in { options.bagel.services.vault = { enable = mkEnableOption "the OpenBao (Vault fork) service"; domain = mkOption { type = types.str; default = config.networking.fqdn; defaultText = "config.networking.fqdn"; example = "vault.infra.forkos.org"; }; peers = mkOption { type = types.listOf types.str; default = [ ]; description = "List of FQDN that are peers of this service"; }; }; imports = [ ./module.nix ]; config = mkIf cfg.enable { networking.firewall.allowedTCPPorts = [ # NGINX HTTP API access 80 443 # mTLS backed cluster port 8201 ]; services.nginx = { enable = true; recommendedProxySettings = true; virtualHosts."${cfg.domain}" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://127.0.0.1:8200"; }; }; }; services.openbao = { enable = true; storageBackend = "raft"; listenerExtraConfig = '' cluster_address = "${wanAddress}:8201" ''; storageConfig = '' node_id = "${config.networking.fqdn}" # Other nodes of the cluster. ${concatStringsSep "\n" (map mkPeerNode cfg.peers)} ''; extraConfig = '' cluster_addr = "http://${config.networking.fqdn}:8201" api_addr = "https://${config.networking.fqdn}" ''; }; }; }