-
-
Notifications
You must be signed in to change notification settings - Fork 18.1k
Description
Context & motivation
In NixOS, a desirable property is that the current state of the system configuration is a pure function of the Nix expression evaluated.
For example, NGINX virtual hosts are directly a pure function of the Nix expressions describing them.
Another example would be that, under users.mutableUsers = false;, UNIX users are directly a pure a function of the Nix expressions describing them, including their attributes. (please correct me if this is wrong.)
A non-example of this is services.postgresql.ensureUsers, it is possible to manually remove a PostgreSQL user and perform multiple rebuild switch without reviving the user in question, therefore, creating a drift between NixOS expression and the actual PostgreSQL configuration.
Same thing for hardware.ensurePrinters too (which attempt to reconcile the expression with the reality, without removing any printer though.)
This can be generalized into all kind of options that "prefill" data or state which could also be seen as "static configuration state" (e.g. what are my users, what are their permissions, etc.) but could also have been dynamic.
Recently, there have been some activity to extend ensure-style options to existing NixOS modules for the sake of usability and, that under "nice assumptions" (no manual removal, not too much buggy software, etc.), they would even respect the "purity" predicate given above (i.e. the configuration state is a pure function of NixOS expression), see:
- services.postgresql: Allow configuration of user roles in ensureUser #200724
- Enrich PostgreSQL ensure users and databases support #203474
- minio: declarative creation of buckets/groups/policies/users (#89559) #164235
- nixos/keycloak: add realmImportsDirectory config #206729
Arguments against the proliferation of these options
In #164235, @aanderse argued against these kinds of options because they break many assumptions people tend to have on a NixOS system and recommended using a tooling which would actually try to reconcile the state, e.g. Terraform (or NixOps I would say).
Open questions
Personally, I would argue that there are some practical advantages to limit the amount of tooling used to deploy a system and Terraform/NixOS integration is not necessarily optimal, therefore, I think this matter should be more discussed.
(1) Who is using NixOS with strong assumptions based on the fact they can derive more or less static configuration state based on NixOS expression? Is there any term to describe this property we can start using in the community and document it?
(2) Should we introduce a tainting mechanism whenever a property-breaking option is being used so that this group of users can isolate these systems? Should we do nothing and just try actively to remove these mechanisms? What is a good story for these competing needs?
(3) What is an acceptable way to perform these "reconciliation" operations à la Kubernetes/Terraform/Ansible in NixOS? Should we start work on a framework to contribute those to nixpkgs?
Another connected problem which is related but not directly is the "automatic migration" mechanism that tend to be present for NixOS module for simplicity, but creates real issues when in combination with rollback feature, e.g. upgrading Gitea, Gitea is broken, then rollbacking and Gitea revision N - 1 is not forward compatible with the new DB schema, therefore, Gitea is broken on previous revision too. I do think answering questions here would provide some insights regarding this problem too.