The NixOps resources.machines option

By Robin Gloster | Fri, 10. Oct 2018

The resources.machines attribute set

NixOps provides the evaluated node configurations of a deployment network in the resources.machines attribute set. Using this information, one can easily implement machine configurations that are generated from options in an existing network.

For example, a reverse proxy that automatically proxies to all other webservers in the network—one which could handle TLS termination for all of them—can be generated without having to manually define individual virtual hosts.

Example deployment

In this deployment, all machines running an nginx are automatically proxied to from a caddy reverse proxy. Adding another webserver will result in the caddy config being updated on deployment.

This example uses the NixOps libvirt backend for easier testing, but can be substituted to whatever fits your needs.

 1# resources-test.nix
 2let
 3  # helper function to easily create some machines running nginx
 4  serve = (proxyTarget: {
 5    deployment.targetEnv = "libvirtd";
 6    networking.firewall.allowedTCPPorts = [ 80 ];
 7    services.nginx = {
 8      enable = true;
 9      virtualHosts.localhost.locations."/".proxyPass = "${proxyTarget}";
10    };
11  });
12in
13{
14  network.description = "nixops RESOURCES test network";
15
16  reverse-proxy = { resources, lib, ... }: with lib; let
17    # get an attrs of machines that have nginx enabled
18    nginxMachines = filterAttrs (_: v: v.services.nginx.enable) resources.machines;
19  in {
20    deployment.targetEnv = "libvirtd";
21    services.caddy = {
22      enable = true;
23      # map the list of nginx machines to a caddy configuration
24      # proxying ${name}.localhost -> ${name}
25      config = toString (flip mapAttrsToList nginxMachines (machine: v: ''
26        http://${machine}.localhost {
27          proxy / ${v.networking.hostName}
28        }
29      ''));
30    };
31  };
32  nixos = serve "https://nixos.org";
33  nixpkgs = serve "https://github.com/nixos/nixpkgs";
34}

Then create the deployment and curl one of the machines from the reverse proxy:

$ nixops create resources-test.nix -d resources-test
$ nixops deploy -d resources-test
$ nixops ssh -d resources-test reverse-proxy
[root@reverse-proxy:~]# curl http://nixos.localhost

The domain *.localhost always resolves to 127.0.0.1, simplifying this example to not need a special DNS setup.

Another viable use of resources.machines would be to create an automatic monitoring configuration, generating the targets from other existing machines and services, as implemented in the Mayflower monitoring module. We will dive deeper into that in an upcoming blog post.

Do you have a question about Nix?

Just ask us! We would love to talk to you!

Check out our crew