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.