Skip to content

RFC: ensure-style options in NixOS modules #206467

@RaitoBezarius

Description

@RaitoBezarius

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:

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    0.kind: questionRequests for a specific question to be answered6.topic: best practicesDocumentation and discussion around best practices for Nixpkgs development6.topic: nixosIssues or PRs affecting NixOS modules, or package usability issues specific to NixOS6.topic: policy discussionDiscuss policies to work in and around Nixpkgs6.topic: user experienceNixOS / Nixpkgs end user experience

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions