| config | ||
| hosts | ||
| lib | ||
| modules | ||
| pkgs | ||
| default.nix | ||
| README.md | ||
NixOS configuration facilities for CCC Bremen infrastructure
Structure
The top-level directories modules, hosts, and config differentiate
between three types, namely NixOS modules, host modules, and
configuration modules, respectively.
A NixOS module is an ordinary module used for parametrizable
configuration tasks much like upstream NixOS modules. The only
difference is that the NixOS modules provided in this repository are
namespaced under ccchb, i.e. options are located under the ccchb
hierarchy. For instance, the option ccchb.common.enable enables the
NixOS module ccchb.common, which is located in modules/common.nix.
A host module declares the system configuration of a single
host, up to hardware-dependent settings usually defined in the local
hardware-configuration.nix. Instructive examples are hosts/mail.nix
and hosts/doord-pi-1.nix. In order to build, for example, an image
for the host doord-pi-1.nix, one may use
nixos-rebuild build-image -I nixos-config=./hosts/doord-pi-1.nix \
--image-variant sd-card
The more common alternative is to checkout this repository to a host,
which is configured by a host module, and import the host module in
/etc/nixos/configuration.nix:
{ config, lib, pkgs, ... }: {
imports = [
./hardware-configuration.nix
./nixos-configuration/hosts/mail.nix
];
}
Lastly, a configuration module contains commonly used configuration options. See below in the section Configuration modules for more details.
Workflow
This repository contains custom NixOS modules, which describe concrete hosts. As these hosts are actual deployments and these are stateful in their nature, the challenge is to track this state as faithful as possible in the version control (i.e. this Git repository).
The main branch tracks the latest modifications of the modules. It is where changes are to be committed and/or merged, depending on the details of the workflow. Furthermore, the main branch is the basis for new deployments: Specification of new deployments happens first in the main branch. Then, new deployments are deployed from the main branch.
The state of every deployment is tracked by an individual branch with the
prefix deploy/, which is called the deployment branch of a deployment.
This branch is supposed to reflect the actual state of the deployment.
Moreover, the deployment branch of a deployment is the checkout branch
for the copy of this repository on that deployment.
The user may choose two tactics when updating a deployment branch on modification of a deployment:
- They can decide to commit the changes to main, and then merge/rebase the main branch into the deployment branch. Then, they fetch the updated deployment branch on the checkout on the deployment, and perform the necessary steps to deploy the changes. If this fails, the deployment branch is ahead of the state of the actual deployment.
- They can commit the changes to main, checkout the main branch on the deployment, and perform the steps to deploy the changes. Then, after doing the deployment, they reset the deployment branch to the main branch. This guarantees that the deployment branch always reflects the state of the actual deployment, given the user does not forget to reset the deployment branch after deploying.
Configuration modules
Users
Users may be declared globally in the config/users.nix module, and
instantiated on a per-host basis by setting users.users accordingly.
For example,
{ local, ... }: { {
users.users = local.lib.callUsers {
inherit (local.config.users) fritz genofire crest humm;
} { };
}
instantiates the users fritz, genofire, crest, and humm.
Technically, a user under local.config.users is a module, which
can be instantiated by the local.lib.callUser library function.
Each user module currently receives the following, well-known arguments:
adminGroups: A list of common admin groups for NixOSdesktopGroups: A list of common desktop groups for NixOS
Mail accounts and forwardings
Mail accounts and forwardings are declared globally in the
config/mail-accounts.nix module. Each mail account is represented by
an attribute set, with the following keys:
forwardTo(optional): Email address for forwardinghashedPassword(optional): Password hash for Dovecotaliases(optional): List of email addresses that alias the declared account
Mail accounts can be transformed by using the local.lib.callMailAccount
library function to a attribute set consisting of a passwd line for
Dovecot, a vmailbox line for virtual_mailbox_maps in Postfix, and
virtual lines for virtual_alias_maps in Postfix. The library function
callMailAccount receives the canonical mail address for the account
as its first argument, and the attribute set describing the mail account
as its second argument. For example,
local.lib.callMailAccount "test@ccchb.de" {
aliases = [
"test2@ccchb.de"
];
forwardTo = "test3@ccchb.de";
hashedPassword = "...";
}
creates the required map entries for the mail account "test@ccchb.de", which has the alias "test2@ccchb.de", forwards mail to "test3@ccchb.de", and has a hashedPassword declared for authentication purposes (e.g. SMTP and IMAP).