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