Merging attribute sets with NixOps

Hey!

I am trying to factor a bit a configuration for NixOps. Here is my current take:

{ config, pkgs, lib, nodes, ... }:
 vhost = name: attrs: {
   # Virtualhost definition
   services.nginx = {
     virtualHosts."${name}" = {
       root = "/data/webserver/${name}";
       enableACME = true;
       forceSSL = true;
     } // attrs;
   };

   # Let's encrypt extra configuration
   security.acme = {
     certs."${name}" = {
       email = "letsencrypt@me";
     };
   };
  };
in
{
  services.nginx = {
    enable = true;
    [...]
  };
} // vhost "web.example.com" {
  extraConfig = 'expires 1h;';
}

With this, I get an error like that:

error: The option `security.acme.certs.web.example.com.webroot' is used but not defined.

I can fix the error by adding services.nginx.enable = true in the vhost function. But in this case, the whole config in the first block is ignored. From my understanding, I don’t correctly extend the first attribute set with the second one. The whole services.nginx definition is replaced by the one in the vhost function. What is the proper way to factor configuration? I’ve also tried to use mkMerge, but it seems to be not different.

1 Like

Hi bernat,

I see two issues with your code. First it is missing a let keyword.
You should also be aware that // updates attributes at the topmost level.
So the service attribute from

{
  services.nginx = {
    enable = true;
    [...]
  };
}

gets replaced by (not merged with) the one from

vhost "web.example.com" {
  extraConfig = 'expires 1h;';
}

To merge config options, you should use other mechanisms like the imports attribute or mkMerge.

Regards,

– Layus.

2 Likes

Hey!

Thanks for your help! I had tried mkMerge but was unsuccessful because I was using:

lib.mkMerge(
{ ... }
vhost "web.example.com" { ... })

But with an extra pair of parentheses, this works:

lib.mkMerge(
{ ... }
(vhost "web.example.com" { ... }))
2 Likes

assuming that you mean lib.mkMerge [ ... ] then you are indeed victim of the need to parenthesize within lists in nix [1].

[1] Data Types - Nix Reference Manual

1 Like