Insert a line in a module's systemd script definition

Brief overview of what I’m trying to accomplish: Grafana has native support for Oauth and one of the required pieces of configuration is a shared secret between Grafana and the Oauth service (in this case I’m using Authelia). I don’t want the value of the secret to be world-readable in the nix store and I’ve managed this in the past with sops-nix and having the service in question read the secret from the sops secret store at runtime. I’m defining Grafana’s configuration via a settings block that gets formatted to ini during system rebuild which doesn’t have facilities for getting values from files as far as I know.

Fortunately(?) Grafana can set configuration values via environment variables so I’m hoping to add a line like export GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET=$(cat /run/secrets/grafana_secret) to the systemd.services.grafana.script definition from the grafana module. I’d prefer to prepend the variable definition line to the module’s script definition rather than manually redefine the script with the variable export added.

I attempted to do it via systemd.services.grafana.script = "export GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET=$(cat /run/secrets/nginx/grafana/oauth_secret)" + config.systemd.services.grafana.script; but got an infinite recursion error. Is there an established practice for modifying a module element definition rather than totally redefining it?

This should work:

systemd.services.grafana.script = lib.mkBefore ''
  export 
GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET=$(cat 
/run/secrets/nginx/grafana/oauth_secret)
";

Because of the type of the script option in systemd services, strings set from any module get merged by default so you don’t need to append the existing script line. And you got the infinite recursion error because you tried to reference the result of the script option while changing the script option. lib.mkBefore will make sure that the export string is at the start of the script.

It actually does:

{
  services.grafana.settings."auth.generic_oauth".client_secret = "\$__file{${config.sops.grafana_oauth_secret.path}}";
}

Please note that the $__file{} thing is a Grafana feature, so it’s not applicable to other services.

Thank you uncovering that, I hadn’t seen that documented.