at 24.11-pre 4.2 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 format = pkgs.formats.json { }; 7 commonOptions = { pkgName, flavour ? pkgName }: mkOption { 8 default = { }; 9 description = '' 10 Attribute set of ${flavour} instances. 11 Creates independent `${flavour}-''${name}.service` systemd units for each instance defined here. 12 ''; 13 type = with types; attrsOf (submodule ({ name, ... }: { 14 options = { 15 enable = mkEnableOption "this ${flavour} instance" // { default = true; }; 16 17 package = mkPackageOption pkgs pkgName { }; 18 19 user = mkOption { 20 type = types.str; 21 default = "root"; 22 description = '' 23 User under which this instance runs. 24 ''; 25 }; 26 27 group = mkOption { 28 type = types.str; 29 default = "root"; 30 description = '' 31 Group under which this instance runs. 32 ''; 33 }; 34 35 settings = mkOption { 36 type = types.submodule { 37 freeformType = format.type; 38 39 options = { 40 pid_file = mkOption { 41 default = "/run/${flavour}/${name}.pid"; 42 type = types.str; 43 description = '' 44 Path to use for the pid file. 45 ''; 46 }; 47 48 template = mkOption { 49 default = [ ]; 50 type = with types; listOf (attrsOf anything); 51 description = 52 let upstreamDocs = 53 if flavour == "vault-agent" 54 then "https://developer.hashicorp.com/vault/docs/agent/template" 55 else "https://github.com/hashicorp/consul-template/blob/main/docs/configuration.md#templates"; 56 in '' 57 Template section of ${flavour}. 58 Refer to <${upstreamDocs}> for supported values. 59 ''; 60 }; 61 }; 62 }; 63 64 default = { }; 65 66 description = 67 let upstreamDocs = 68 if flavour == "vault-agent" 69 then "https://developer.hashicorp.com/vault/docs/agent#configuration-file-options" 70 else "https://github.com/hashicorp/consul-template/blob/main/docs/configuration.md#configuration-file"; 71 in '' 72 Free-form settings written directly to the `config.json` file. 73 Refer to <${upstreamDocs}> for supported values. 74 75 ::: {.note} 76 Resulting format is JSON not HCL. 77 Refer to <https://www.hcl2json.com/> if you are unsure how to convert HCL options to JSON. 78 ::: 79 ''; 80 }; 81 }; 82 })); 83 }; 84 85 createAgentInstance = { instance, name, flavour }: 86 let 87 configFile = format.generate "${name}.json" instance.settings; 88 in 89 mkIf (instance.enable) { 90 description = "${flavour} daemon - ${name}"; 91 wantedBy = [ "multi-user.target" ]; 92 after = [ "network.target" ]; 93 path = [ pkgs.getent ]; 94 startLimitIntervalSec = 60; 95 startLimitBurst = 3; 96 serviceConfig = { 97 User = instance.user; 98 Group = instance.group; 99 RuntimeDirectory = flavour; 100 ExecStart = "${getExe instance.package} ${optionalString ((getName instance.package) == "vault") "agent"} -config ${configFile}"; 101 ExecReload = "${pkgs.coreutils}/bin/kill -SIGHUP $MAINPID"; 102 KillSignal = "SIGINT"; 103 TimeoutStopSec = "30s"; 104 Restart = "on-failure"; 105 }; 106 }; 107in 108{ 109 options = { 110 services.consul-template.instances = commonOptions { pkgName = "consul-template"; }; 111 services.vault-agent.instances = commonOptions { pkgName = "vault"; flavour = "vault-agent"; }; 112 }; 113 114 config = mkMerge (map 115 (flavour: 116 let cfg = config.services.${flavour}; in 117 mkIf (cfg.instances != { }) { 118 systemd.services = mapAttrs' 119 (name: instance: nameValuePair "${flavour}-${name}" (createAgentInstance { inherit name instance flavour; })) 120 cfg.instances; 121 }) 122 [ "consul-template" "vault-agent" ]); 123 124 meta.maintainers = with maintainers; [ emilylange tcheronneau ]; 125} 126