at 23.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 = mdDoc '' 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 (mdDoc "this ${flavour} instance") // { default = true; }; 16 17 package = mkPackageOptionMD pkgs pkgName { }; 18 19 user = mkOption { 20 type = types.str; 21 default = "root"; 22 description = mdDoc '' 23 User under which this instance runs. 24 ''; 25 }; 26 27 group = mkOption { 28 type = types.str; 29 default = "root"; 30 description = mdDoc '' 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 = mdDoc '' 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 mdDoc '' 58 Template section of ${flavour}. 59 Refer to <${upstreamDocs}> for supported values. 60 ''; 61 }; 62 }; 63 }; 64 65 default = { }; 66 67 description = 68 let upstreamDocs = 69 if flavour == "vault-agent" 70 then "https://developer.hashicorp.com/vault/docs/agent#configuration-file-options" 71 else "https://github.com/hashicorp/consul-template/blob/main/docs/configuration.md#configuration-file"; 72 in 73 mdDoc '' 74 Free-form settings written directly to the `config.json` file. 75 Refer to <${upstreamDocs}> for supported values. 76 77 ::: {.note} 78 Resulting format is JSON not HCL. 79 Refer to <https://www.hcl2json.com/> if you are unsure how to convert HCL options to JSON. 80 ::: 81 ''; 82 }; 83 }; 84 })); 85 }; 86 87 createAgentInstance = { instance, name, flavour }: 88 let 89 configFile = format.generate "${name}.json" instance.settings; 90 in 91 mkIf (instance.enable) { 92 description = "${flavour} daemon - ${name}"; 93 wantedBy = [ "multi-user.target" ]; 94 after = [ "network.target" ]; 95 path = [ pkgs.getent ]; 96 startLimitIntervalSec = 60; 97 startLimitBurst = 3; 98 serviceConfig = { 99 User = instance.user; 100 Group = instance.group; 101 RuntimeDirectory = flavour; 102 ExecStart = "${getExe instance.package} ${optionalString ((getName instance.package) == "vault") "agent"} -config ${configFile}"; 103 ExecReload = "${pkgs.coreutils}/bin/kill -SIGHUP $MAINPID"; 104 KillSignal = "SIGINT"; 105 TimeoutStopSec = "30s"; 106 Restart = "on-failure"; 107 }; 108 }; 109in 110{ 111 options = { 112 services.consul-template.instances = commonOptions { pkgName = "consul-template"; }; 113 services.vault-agent.instances = commonOptions { pkgName = "vault"; flavour = "vault-agent"; }; 114 }; 115 116 config = mkMerge (map 117 (flavour: 118 let cfg = config.services.${flavour}; in 119 mkIf (cfg.instances != { }) { 120 systemd.services = mapAttrs' 121 (name: instance: nameValuePair "${flavour}-${name}" (createAgentInstance { inherit name instance flavour; })) 122 cfg.instances; 123 }) 124 [ "consul-template" "vault-agent" ]); 125 126 meta.maintainers = with maintainers; [ emilylange tcheronneau ]; 127} 128