How to import nixos config and merge it with nixops deployment expression

1.4k views Asked by At

I'm in the process of learning how to use Nix/NixOs/NixOps, and I'm having trouble refactoring a simple NixOps deployment.

My starting point is this working vbox-all.nix file :

{
    server =
        { config, pkgs, ... }:
        {
            # deployment-specific config
            deployment.targetEnv = "virtualbox";
            deployment.virtualbox.memorySize = 1024; # megabytes
            deployment.virtualbox.vcpu = 2; # number of cpus

            # postgres-specific config
            services.postgresql.enable = true;
            services.postgresql.package = pkgs.postgresql96;

            # htop-specific config
            environment.systemPackages =
            [
                pkgs.htop
            ];
        };
}

Running nixops create ./vbox.nix -d mydeployment and then nixops deploy -d mydeployment works perfectly : I get a VirtualBox machine with Postgres 9.6 running and htop installed.

Now, having all of this in one file does not seem to be a good idea for long term maintenance.

Here is the file layout I think I want:

.
├── configuration-all.nix # forms a NixOs config with htop, postgres, etc.
├── htop.nix # NixOs config of just htop
├── postgres.nix # NixOs config of just Postgres
└── vbox-all.nix # NixOps config for virtualbox with htop, postgres, etc.

The idea being that vbox-all.nix imports configuration-all.nix which imports all services/packages/conf I might want (currently postgres and htop).

That's what I cannot get to work.

Here is my configuration-all.nix :

{ config, pkgs, ... }:
{
    imports = [ ./postgres.nix ./htop.nix ];
}

Here is ./postgres.nix :

{ config, pkgs, ... }:
{
    services.postgresql.enable = true;
    services.postgresql.package = pkgs.postgresql96;
}

I think you can guess the content of ./htop.nix, and it doesn't really matter anyway.

And finally, my modified vbox-all.nix:

{
    server =
        { config, pkgs, ... }:
        with (pkgs.callPackage ./configuration-all.nix { });
        {
            # deployment-specific config
            deployment.targetEnv = "virtualbox";
            deployment.virtualbox.memorySize = 1024; # megabytes
            deployment.virtualbox.vcpu = 2; # number of cpus
        };
}

When I re-run nixops deploy -d mydeployment, I don't get any errors but the resulting VM doesn't have neither postgres nor htop.

I must be fundamentally misunderstanding either with or callPackage. For me it should : execute the function defined in ./configuration-all.nix (auto-filling all args) and merge the resulting expression with my "deployment-specific config".

I tried a few things like: replacing pkgs.callPackage with import (still no error, but still no good), using inherit (pkgs.callPackage ./configuration-all.nix { }) instead of with, etc. but so far no dice.

I must be missing something small and probably obvious...

1

There are 1 answers

0
HectorJ On BEST ANSWER

Here is my final working vbox-all.nix I figured out while writing my question.

{
    server =
    {
        imports = [ ./configuration-all.nix ];
        # deployment-specific config
        deployment.targetEnv = "virtualbox";
        deployment.virtualbox.memorySize = 1024; # megabytes
        deployment.virtualbox.vcpu = 2; # number of cpus
    };
}

Thanks SO, you're a good rubber duck.

I still need to understand why my other attempts with with and inherit did not work, so don't hesitate to comment or post an alternative answer. I have a lot to learn.