Hi.
I’ve just seen this video about using the config and option to modularize my configuration. https://www.youtube.com/watch?v=vYc6IzKvAJQ
I would like to implement this into my current configuration, however my first attempt has resulted in an error, I’m trying to modularize this Wireguard configuration, and I’m using sops-nix to provide the private and preshared keys to the configuration.
Here is the code:
{ pkgs, lib, config, ...}: {
options = {
wireguard = {
enable = lib.mkEnableOption "Enable Wireguard";
};
};
config = {
sops.secrets.wireguard = {
format = "yml";
sopsFile = path/to/secrets.yml;
};
networking.wireguard.interfaces = {
wg0 = {
...
privateKeyFile = config.sops.secrets.wireguard.private_key.path;
...
peers = [
{
...
presharedKeyFile = config.sops.secrets.wireguard.preshared_key.path;
...
}
];
};
};
};
}
The error I’m receiving:
error: undefined variable 'config' in config.sops.secrets.wireguard.preshared_key.path]
From my limited understanding, I believe this is because the sops-nix module also uses config, and defining it here messes with it meaning that the secrets aren’t available here? (If anyone in a response could also explain this to me, that would be incredibly helpful
)
Is there anything I’m able to do to fix this? I’ve seen this type of solution where a configuration file is created with the secrets, and inserted into the wireguard option Sops-nix templates in config file - #2 by firecat53 however I don’t think this will work for something like container environment variables?
Thanks for the help!
If you actually have this^
then the error you have is not possible, unless there’s an upstream bug. But also, you obscured the stacktrace; an error without a stacktrace is useless.
Show the whole stacktrace with --show-trace and as much of the file as you can.
I don’t know what you mean, other than you don’t understand the module system.
I suggest reading https://nixos.org/manual/nixos/stable/#sec-writing-modules.
My apologies, I obfuscated the fact that I was using a variable to call this because I thought it had made no difference. (meaning that I’ve got another file called vars.nix, that’s put into the input and then references with “${vars.private_key}”. I thought I had tested this, but apparently not.
The reason for using a variable in the first place was so that I could call in a different private key per host, so I’d be able to reuse the same wireguard module for every host that I’ve got (as they all have different private keys), but looks like that solution wouldn’t work.
So from the start, not skipping out any steps.
vars.nix
{
wg_private_key = config.sops.secrets.wireguard.private_key.path;
wg_preshared_key = config.sops.secrets.wireguard.preshared_key.path;
}
wireguard.nix
{ pkgs, lib, config, vars, ...}: {
options = {
wireguard = {
enable = lib.mkEnableOption "Enable Wireguard";
};
};
config = {
sops.secrets.wireguard = {
format = "yml";
sopsFile = path/to/secrets.yml;
};
networking.wireguard.interfaces = {
wg0 = {
...
privateKeyFile = "${vars.wg_private_key}" ...
peers = [
{
...
presharedKeyFile = "${vars.wg_preshared_key}"
...
}
];
};
};
};
}
relevant part in flake.nix where I import the variables:
nixosConfigurations = {
server = nixpkgs.lib.nixosSystem {
specialArgs = {
inherit inputs;
vars = import ./hosts/server/vars.nix;
};
modules = [
sops-nix.nixosModules.sops
...
];
};
...
};
stack trace (using deploy-rs but it fails in the build part):
Ah okay, the fix is simpler then.
Remove vars from specialArgs, turn vars.nix into an actual module, by structuring it as below:
{ config, ... }:
{
_module.args.vars = {
# define stuff here
};
}
and then use vars.nix as a module (by adding it to imports in some other module).
The reason your code doesn’t work is because you never brought config into scope in that file - the file is not a function, and you’re also outside of the module system when you use specialArgs, so there’s doubly no way for you to provide config to it.
1 Like
Wow that worked!
Thanks for being so patient with me!