{ config, lib, pkgs, ... }: with lib; let cfg = config.services.hashicorp-envoy; serviceFormat = pkgs.formats.json {}; in { options.services.hashicorp-envoy = mkOption { description = mdDoc '' ''; type = types.attrsOf (types.submodule { options = { service = mkOption { description = mdDoc '' ''; type = serviceFormat.type; }; environment = mkOption { description = mdDoc '' ''; type = with types; attrsOf str; default = {}; }; adminBind = mkOption { description = mdDoc '' ''; type = types.str; }; consulPackage = mkOption { description = mdDoc '' ''; type = types.package; default = pkgs.consul; }; envoyPackage = mkOption { description = mdDoc '' ''; type = types.package; default = pkgs.envoy; }; }; }); default = {}; }; config = { services.hashicorp = flip mapAttrs' cfg (name: value: nameValuePair "envoy-${name}" { enable = true; package = pkgs.consul; command = "connect envoy"; extraArguments = [ "-sidecar-for" value.service.id "-admin-bind" value.adminBind "-address" (value.service.connect.sidecar_service.address or "0.0.0.0" + ":" + toString value.service.connect.sidecar_service.port or "19000") ]; extraPackages = [ value.envoyPackage ]; dontUseConfig = true; } ); systemd.services = flip mapAttrs' cfg (name: value: nameValuePair "hashicorp-envoy-${name}" { preStart = "${value.consulPackage}/bin/consul services register ${serviceFormat.generate "${name}-service.json" { service = value.service; }}"; postStop = "${value.consulPackage}/bin/consul services deregister -id=${value.service.id}"; environment = value.environment; } ); }; }