I have to rewrite some user definition for a server.
Right now the code looks like this:
let
sshkeys = pkgs.fetchFromGitHub {
owner = "abc";
repo = "def";
rev = "123";
sha512 = "456";
};
getpubkeys = user: builtins.readFile "${sshkeys}/${user}.pub";
mkuser = user: { name = user; isNormalUser = true; extraGroups = [ "wheel" ]; initialPassword = "hdsklf"; openssh.authorizedKeys.keys = [ (getpubkeys user) ]; };
mkusers = users: map (mkuser) users;
in
{
users.users = mkusers [ "alice" "bob" "charlie" ] ++ [
{ name = "dana"; isNormalUser = true; extraGroups = [ "wheel" ]; openssh.authorizedKeys.keys = [
"ssh-rsa AAAA..."
]; }
];
}
This is working fine, except since 20.03 I get a message that it will be deprecated soon.
It allows me to have a simple list where users can be added to be granted access, they only have to login with their key and then can change their password.
How do I change these lines to create an attribute set instead?
I’m stuck with no idea where to begin - I’m using NixOS for quite some years now but pretty much never used functions to generate my config.
Perhaps there is a better way but my first inclination would be to use lib.genAttrs
function like so:
nix-repl> let mkUser = user: { isNormalUser = true; }; in lib.genAttrs [ "alice" "bob" ] (user: mkUser user)
{ alice = { ... }; bob = { ... }; }
1 Like
Thank you, that was the help I needed. 
My full solution is now this:
let
sshkeys = pkgs.fetchFromGitHub {
owner = "abc";
repo = "def";
rev = "123";
sha512 = "456";
};
getpubkeys = user: builtins.readFile "${sshkeys}/${user}.pub";
mkuser = user: { name = user; isNormalUser = true; extraGroups = [ "wheel" ]; initialPassword = "hdsklf"; openssh.authorizedKeys.keys = [ (getpubkeys user) ]; };
in
{
users.users = (lib.genAttrs [ "alice" "bob" "charlie" ] mkuser) // {
dana = { name = "dana"; isNormalUser = true; extraGroups = [ "wheel" ]; openssh.authorizedKeys.keys = [
"ssh-rsa AAAA..."
]; };
};
}
Rebuilding the system does not even change the hash, so it results in exactly the same output as before.
Update: included @lheckemann’s suggestion
3 Likes
(user: mkuser "${user}")
can be simplified to mkuser

1 Like
although you’re not using it anymore, this can be simplified to mkusers = map mkuser
through eta reduction.
https://wiki.haskell.org/Eta_conversion