4 files changed
--- /dev/null
+++ b/docs/index.adoc
@@ -0,0 +1,78 @@
+
+= Fleet
+:slug: index
+:order: 0
+
+An NixOS cluster deployment tool.
+
+== Advantages over existing configuration systems (NixOps/Morph)
+
+- Modules can configure multiple hosts at once (i.e. for wireguard/kubernetes installation)
+- Secrets can be securely stored in Git (no one except target hosts can decrypt them), automatically regenerated, reencrypted, etc.
+- Automatic rollback on deployment failure, which will work as long as system is passing initrd stage
+
+== Flake example
+
+[source,nix]
+----
+{
+ description = "My cluster configuration";
+ inputs = {
+ nixpkgs.url = "github:nixos/nixpkgs";
+ fleet = {
+ url = "github:CertainLach/fleet";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ flake-parts.url = "github:hercules-ci/flake-parts";
+ };
+ outputs = inputs:
+ inputs.flake-parts.lib.mkFlake {inherit inputs;} {
+ imports = [inputs.fleet.flakeModules.default];
+
+ fleetConfigurations.default = {
+ nixos = {
+ # Shared NixOS configuration for all hosts
+ };
+
+ imports = [
+ ./wireguard
+ ];
+
+ hosts.controlplane-1 = {
+ system = "x86_64-linux";
+ nixos = {
+ imports = [
+ ./controlplane-1/hardware-configuration.nix
+ ./controlplane-1/configuration.nix
+ ];
+ };
+ };
+ };
+ };
+}
+----
+
+== Secret generator example
+
+[source,nix]
+----
+{config, ...}: {
+ secrets = {
+ gitlab-initial-root = {
+ generator = {mkPassword}: mkPassword {};
+ owner = "gitlab";
+ group = "gitlab";
+ };
+ gitlab-secret = {
+ generator = {mkPassword}: mkPassword {};
+ owner = "gitlab";
+ group = "gitlab";
+ };
+ };
+ services.gitlab = {
+ enable = true;
+ initialRootPasswordFile = config.secrets.gitlab-initial-root.secretPath;
+ secrets.secretFile = config.secrets.gitlab-secret.secretPath;
+ };
+}
+----
--- /dev/null
+++ b/docs/migration.adoc
@@ -0,0 +1,42 @@
+
+= Migration Guide
+:slug: migration
+:order: 2
+
+== fleet.nix <unset> => 0.1.0
+
+Add version field::
+Set it to 0.1.0; This field specifies which version of fleet do you use for cluster management, breaking changes will also break this value to make sure you read this guide.
+
+Move every secret part::
+Before it was only public and private, now it can be any number of parts.
+
+In your fleet.nix file, look at every record like this:
+[source,nix]
+----
+gitlab-initial-root = {
+ createdAt = "2024-03-01T15:54:32.983358495Z";
+ public = "example";
+ secret = "vp%d6wO#0#D2.../dgCA+v4Gf:YG";
+};
+----
+
+And modify it as following:
+[source,nix]
+----
+gitlab-initial-root = {
+ createdAt = "2024-03-01T15:54:32.983358495Z";
+ public.raw = "<PLAINTEXT>example";
+ secret.raw = ''
+ <ENCRYPTED><Z85-ENCODED>
+ vp%d6wO#0#D2.../dgCA+v4Gf:YG
+ '';
+};
+----
+
+Default encoding was also changed from `Z85` to `base64`. This conversion will be done by fleet automatically.
+
+Update references to secrets in fleet/nixos configurations::
+Instead of `config.secrets.secret-name.secretPath` use `config.secrets.secret-name.secret.path`,
+instead of `config.secrets.secret-name.stableSecretPath` use `config.secrets.secret-name.secret.stablePath`,
+instead of `config.secrets.secret-name.public` use `config.secrets.secret-name.public.data`.
--- a/docs/secrets.adoc
+++ b/docs/secrets.adoc
@@ -1,4 +1,6 @@
= Fleet Secrets Management System
+:slug: secrets
+:order: 1
== Overview
1{2 config,3 lib,4 ...5}:6let7 inherit (lib.options) mkOption;8 inherit (lib.modules) mkIf mkDefault;9 inherit (lib.types)10 attrsOf11 str12 submodule13 either14 listOf15 lines16 bool17 ;18 inherit (lib.attrsets) mapAttrs;19 inherit (lib.trivial) isString;20in21{22 options.system.onlineActivationScripts = mkOption {23 default = { };24 type = attrsOf (25 either str (submodule {26 options = {27 deps = mkOption {28 type = listOf str;29 default = [ ];30 };31 text = mkOption {32 type = lines;33 };34 supportsDryActivation = mkOption {35 type = bool;36 default = false;37 };38 };39 })40 );41 description = ''42 Same as activation scripts, but only ran on online activation (i.e when operator is actively running fleet deploy, and not on system restart)4344 Can be used to apply configuration such as ceph monitor maps, which is required to be up-to-date to correctly function,45 we should not apply outdated ceph monmap.46 '';4748 apply =49 set:50 mapAttrs (51 name: value:52 if isString value then53 {54 text = ''55 if [ ! -z ''${FLEET_ONLINE_ACTIVATION+x} ]; then56 ${value}57 fi58 '';59 deps = [ "onlineActivation" ];60 }61 else62 value63 // {64 deps = [ "onlineActivation" ] ++ value.deps;65 text = ''66 if [ ! -z ''${FLEET_ONLINE_ACTIVATION+x} ]; then67 ${value.text}68 fi69 '';70 }71 ) set;72 };7374 config = {75 systemd.targets.online-activation = {76 description = "Online activation target for deploy-time services";77 };7879 system.activationScripts = {80 onlineActivation = {81 text = ''82 if [ ! -z ''${FLEET_ONLINE_ACTIVATION+x} ]; then83 1>&2 echo "online activation; hello, fleet!"84 systemctl start online-activation.target85 fi86 '';87 supportsDryActivation = true;88 };89 }90 // config.system.onlineActivationScripts;9192 systemd.services = mkIf config.networking.networkmanager.enable {93 94 95 96 97 NetworkManager.restartIfChanged = mkDefault false;98 };99 };100}