kg revised this gist 1 month ago. Go to revision
1 file changed, 10 insertions, 3 deletions
deploy-host.nix
| @@ -1,4 +1,4 @@ | |||
| 1 | - | (pkgs.writers.writeNuBin "deploy" | |
| 1 | + | (writeNuBin "deploy" | |
| 2 | 2 | { | |
| 3 | 3 | makeWrapperArgs = [ | |
| 4 | 4 | "--prefix" | |
| @@ -18,7 +18,14 @@ | |||
| 18 | 18 | } | |
| 19 | 19 | # nu | |
| 20 | 20 | '' | |
| 21 | - | def main [host: string, ip: string, ...args: string]: nothing -> nothing { | |
| 21 | + | # A deployment script utilizing nixos-anywhere | |
| 22 | + | # | |
| 23 | + | # 1. Generates new SSH and Age Keys | |
| 24 | + | # 2. Updates all secrets of that host | |
| 25 | + | # 3. Deploys config with new Keys | |
| 26 | + | @example "Deploy Zarqa" {deploy zarqa 192.168.2.201} | |
| 27 | + | @example "Deploy Zarqa and generate facter.json" {deploy zarqa 192.168.2.201 --generate-hardware-report} | |
| 28 | + | def main [host: string, ip: string, --generate-hardware-report]: nothing -> nothing { | |
| 22 | 29 | # Work on raw YAML text for anchors | |
| 23 | 30 | let raw = open --raw .sops.yaml | |
| 24 | 31 | ||
| @@ -72,7 +79,7 @@ | |||
| 72 | 79 | print # needed so that updatekeys output is shown | |
| 73 | 80 | } | |
| 74 | 81 | ||
| 75 | - | nixos-anywhere --flake $".#($host)" --target-host $"root@($ip)" --extra-files $tempdir ...$args | |
| 82 | + | nixos-anywhere --flake $".#($host)" (if $generate_hardware_report { $"--generate-hardware-config nixos-facter ./modules/hosts/($host)/facter.json" } else { "" }) --target-host $"root@($ip)" --extra-files $tempdir | |
| 76 | 83 | ||
| 77 | 84 | # Remove lingering temp directory. | |
| 78 | 85 | # We only care about the successful case because | |
kg revised this gist 1 month ago. Go to revision
1 file changed, 1 insertion, 1 deletion
deploy-host.nix
| @@ -1,4 +1,4 @@ | |||
| 1 | - | (writeNuBin "deploy" | |
| 1 | + | (pkgs.writers.writeNuBin "deploy" | |
| 2 | 2 | { | |
| 3 | 3 | makeWrapperArgs = [ | |
| 4 | 4 | "--prefix" | |
kg revised this gist 1 month ago. Go to revision
1 file changed, 83 insertions
deploy-host.nix(file created)
| @@ -0,0 +1,83 @@ | |||
| 1 | + | (writeNuBin "deploy" | |
| 2 | + | { | |
| 3 | + | makeWrapperArgs = [ | |
| 4 | + | "--prefix" | |
| 5 | + | "PATH" | |
| 6 | + | ":" | |
| 7 | + | (lib.makeBinPath ( | |
| 8 | + | with pkgs; | |
| 9 | + | [ | |
| 10 | + | sops | |
| 11 | + | git | |
| 12 | + | ssh-to-age | |
| 13 | + | nixos-anywhere | |
| 14 | + | openssh | |
| 15 | + | ] | |
| 16 | + | )) | |
| 17 | + | ]; | |
| 18 | + | } | |
| 19 | + | # nu | |
| 20 | + | '' | |
| 21 | + | def main [host: string, ip: string, ...args: string]: nothing -> nothing { | |
| 22 | + | # Work on raw YAML text for anchors | |
| 23 | + | let raw = open --raw .sops.yaml | |
| 24 | + | ||
| 25 | + | let anchor = $"host_($host)" | |
| 26 | + | if not ($raw | str contains $"&($anchor)") { | |
| 27 | + | error make $"Host anchor ($anchor) not found in .sops.yaml" | |
| 28 | + | } | |
| 29 | + | ||
| 30 | + | let old_age_key = $raw | |
| 31 | + | | parse --regex $"&($anchor) \(?<key>age[0-9a-z]+\)" | |
| 32 | + | | get key.0 | |
| 33 | + | if ($old_age_key | is-empty) { | |
| 34 | + | error make $"Failed to extract old age key for ($anchor)" | |
| 35 | + | } | |
| 36 | + | ||
| 37 | + | # Create temp dir | |
| 38 | + | let tempdir = mktemp -d | |
| 39 | + | let ssh_dir = ($tempdir)/etc/ssh | |
| 40 | + | mkdir $ssh_dir | |
| 41 | + | ||
| 42 | + | let rsa_key = $"($ssh_dir)/ssh_host_rsa_key" | |
| 43 | + | let ed25519_key = $"($ssh_dir)/ssh_host_ed25519_key" | |
| 44 | + | ||
| 45 | + | ssh-keygen -t rsa -b 4096 -f $rsa_key -N "" -C $host | |
| 46 | + | ssh-keygen -t ed25519 -f $ed25519_key -N "" -C $host | |
| 47 | + | ||
| 48 | + | let age_pub = open --raw $"($ed25519_key).pub" | ssh-to-age | |
| 49 | + | ||
| 50 | + | # Replace anchor in raw YAML | |
| 51 | + | $raw | |
| 52 | + | | str replace -r $"&($anchor) age[0-9a-z]+" $"&($anchor) ($age_pub)" | |
| 53 | + | | save --force .sops.yaml | |
| 54 | + | ||
| 55 | + | print $"Updated .sops.yaml for ($host)" | |
| 56 | + | ||
| 57 | + | let git_files = git ls-files | lines | |
| 58 | + | ||
| 59 | + | (open .sops.yaml).creation_rules | |
| 60 | + | | where {|rule| | |
| 61 | + | $rule.key_groups | any {|kg| | |
| 62 | + | $kg.age | any {|k| $k == $age_pub } | |
| 63 | + | } | |
| 64 | + | } | |
| 65 | + | | get path_regex | |
| 66 | + | | par-each {|regex| $git_files | where {|f| $f =~ $regex } } | |
| 67 | + | | flatten | |
| 68 | + | | uniq | |
| 69 | + | | each {|file_to_reencrypt| | |
| 70 | + | print $"Re-encrypting ($file_to_reencrypt)" | |
| 71 | + | sops updatekeys $file_to_reencrypt | |
| 72 | + | print # needed so that updatekeys output is shown | |
| 73 | + | } | |
| 74 | + | ||
| 75 | + | nixos-anywhere --flake $".#($host)" --target-host $"root@($ip)" --extra-files $tempdir ...$args | |
| 76 | + | ||
| 77 | + | # Remove lingering temp directory. | |
| 78 | + | # We only care about the successful case because | |
| 79 | + | # failing means the keys won't be used anyway | |
| 80 | + | rm -rf $tempdir | |
| 81 | + | } | |
| 82 | + | '' | |
| 83 | + | ) | |