commit 8a7123f890bd08d69078fe864c457af103ca80c2
parent 20038216792e3dce8e72fa4c95a574142f76ac13
Author: Tomas Hlavaty <tom@logand.com>
Date: Tue, 10 Sep 2019 23:39:58 +0200
more notes
Diffstat:
M | README | | | 138 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 138 insertions(+), 0 deletions(-)
diff --git a/README b/README
@@ -54,3 +54,141 @@ Install NixOS
$ sudo cryptsetup luksAddKey /dev/sdX
$ sudo cryptsetup luksRemoveKey /dev/sdX
+
+## Deployment
+
+There are several deployment tools for nixos each with pros and cons.
+
+- nixops: tried it, didn't like it. too stateful and fragile.
+
+- hail: did not try. looks abandoned. pulls updates from hydra.
+
+- morph: did not try. looks complex.
+
+- krops: did not try. actively used. builds remotely, which I don't
+ want. A production server should serve specific purpose and things
+ which don't serve that purpose should not be there, i.e. I don't
+ want to build there anything and I don't want the build artefacts to
+ be stored there.
+
+- nixos-rebuild: nixos native command. supports deploying to other
+ machines but doesn't do substitutes, which is a major flaw on
+ asymetric connections with bad upload speed.
+
+nixos-rebuid is actually closest to what I want.
+
+Here is an example of a deployment scripts for several machines, each
+with different nixpkgs. Deployment scripts are first built for all
+machines (can be built and cached by hydra, for example). Running a
+deployment script handles local and remote deployments accordingly.
+Remote deployments immitate "nixos-rebuild switch" but allow
+substitutes by copying the closure first.
+
+Have hw directory with subdir with configuration.nix for each machine.
+hw/default.nix can look something like this:
+
+ # nix-build && ./result/bin/deploy-all
+ # nix-build && ./result/bin/deploy-hostname1
+ # nix-build && ./result/bin/deploy-hostname2
+ let
+ pkgs = import <nixpkgs> {};
+ nixpkgs1809 = fetchTarball {
+ url = https://nixos.org/channels/nixos-18.09/nixexprs.tar.xz;
+ };
+ nixpkgs1903 = fetchTarball {
+ url = https://nixos.org/channels/nixos-19.03/nixexprs.tar.xz;
+ };
+ local = name: nixpkgs:
+ pkgs.writeScript "deploy-local-${name}" ''
+ sudo nixos-rebuild switch \
+ -I nixos-config=./${name}/configuration.nix \
+ -I nixpkgs=${nixpkgs}
+ '';
+ buildSystem = name: nixpkgs:
+ let
+ # https://stackoverflow.com/questions/47655567/how-to-build-a-nixops-deployment-on-hydra
+ pkgs2 = import nixpkgs {};
+ nixosSystem = import (pkgs2.path + "/nixos/lib/eval-config.nix") {
+ inherit (pkgs2) system;
+ modules = [(./. + "/${name}/configuration.nix")];
+ };
+ in nixosSystem.config.system.build.toplevel;
+ remote = name: nixpkgs:
+ let
+ sshName = "${name}.tincnet";
+ system = buildSystem name nixpkgs;
+ pkgs2 = import nixpkgs {};
+ switch = pkgs.writeScript "switch-${name}" ''
+ #!${pkgs2.bash}/bin/bash
+ set -euo pipefail
+ cd /tmp
+ ls -al /nix/var/nix/profiles
+ echo register ${system}
+ sudo nix-env -p /nix/var/nix/profiles/system --set ${system}
+ echo switch
+ sudo nohup ${system}/bin/switch-to-configuration switch
+ ls -al /nix/var/nix/profiles
+ '';
+ in
+ pkgs.writeScript "deploy-remote-${name}" ''
+ #!${pkgs.bash}/bin/bash
+ set -euo pipefail
+ echo starting ${name} to ${sshName}
+ #nix-copy-closure --sign --use-substitutes --to ${sshName} ${switch}
+ nix-copy-closure --gzip --use-substitutes --to ${sshName} ${switch}
+ #nix copy --to ssh://${sshName} ${switch}
+ ssh -t ${sshName} ${switch}
+ echo ok ${name} to ${sshName}
+ '';
+ deploy1 = name: nixpkgs:
+ pkgs.writeScriptBin "deploy-${name}" ''
+ #!${pkgs.bash}/bin/bash
+ set -euo pipefail
+ if test ${name} -eq $(hostname -s); then
+ exec ${local name nixpkgs}
+ else
+ exec ${remote name nixpkgs}
+ fi
+ '';
+ all = [
+ (deploy1 "hostname1" nixpkgs1809)
+ (deploy1 "hostname2" nixpkgs1903)
+ ];
+ in
+ pkgs.buildEnv {
+ name = "deploy";
+ paths = all ++ [
+ (pkgs.writeScriptBin "deploy-all" (''
+ #!${pkgs.bash}/bin/bash
+ set -euo pipefail
+ ''
+ + (pkgs.stdenv.lib.concatMapStrings (x: "${x}\n") all)))
+ ];
+ }
+
+If the closure is not signed, your user needs to be trusted by nix in
+the target machine configuration.nix:
+
+ nix.trustedUsers = ["root" "myuser"];
+
+## Secrets
+
+Nix does not address management of secrets.
+
+What I do, for example, for tinc:
+
+- define the tinc service with empty fields for unknown public keys
+
+- deploy the the tinc service, let it generate the keys on the target
+ machine
+
+- read the public key from the target machine and update the tinc
+ service with the newly acquired public key
+
+- deploy the tinc service for the second time, this time with the
+ public key already filled in
+
+Some NixOS deployment tools try to handle it by creating the secret
+keys somewhere and then pushing them to the target machines. I am not
+convinced that this is the right approach. Secrets should not be
+pushed around unnecessarily.