diff --git a/flake.lock b/flake.lock index 72a66d8..6aed47d 100644 --- a/flake.lock +++ b/flake.lock @@ -21,6 +21,27 @@ "url": "https://git.t-juice.club/torjus/alerttonotify" } }, + "homelab-deploy": { + "inputs": { + "nixpkgs": [ + "nixpkgs-unstable" + ] + }, + "locked": { + "lastModified": 1770443536, + "narHash": "sha256-UufZIVggiioMFDSjKx+ifgkDOk9alNSiRmkvc4/+HIA=", + "ref": "master", + "rev": "95b795dcfd86b7b36045bba67e536b3a1c61dd33", + "revCount": 20, + "type": "git", + "url": "https://git.t-juice.club/torjus/homelab-deploy" + }, + "original": { + "ref": "master", + "type": "git", + "url": "https://git.t-juice.club/torjus/homelab-deploy" + } + }, "labmon": { "inputs": { "nixpkgs": [ @@ -97,6 +118,7 @@ "root": { "inputs": { "alerttonotify": "alerttonotify", + "homelab-deploy": "homelab-deploy", "labmon": "labmon", "nixos-exporter": "nixos-exporter", "nixpkgs": "nixpkgs", diff --git a/flake.nix b/flake.nix index ebcbd6c..95cbcb6 100644 --- a/flake.nix +++ b/flake.nix @@ -21,6 +21,10 @@ url = "git+https://git.t-juice.club/torjus/nixos-exporter"; inputs.nixpkgs.follows = "nixpkgs-unstable"; }; + homelab-deploy = { + url = "git+https://git.t-juice.club/torjus/homelab-deploy?ref=master"; + inputs.nixpkgs.follows = "nixpkgs-unstable"; + }; }; outputs = @@ -32,6 +36,7 @@ alerttonotify, labmon, nixos-exporter, + homelab-deploy, ... }@inputs: let @@ -58,6 +63,7 @@ ) sops-nix.nixosModules.sops nixos-exporter.nixosModules.default + homelab-deploy.nixosModules.default ./modules/homelab ]; allSystems = [ @@ -219,11 +225,12 @@ { pkgs }: { default = pkgs.mkShell { - packages = with pkgs; [ - ansible - opentofu - openbao + packages = [ + pkgs.ansible + pkgs.opentofu + pkgs.openbao (pkgs.callPackage ./scripts/create-host { }) + homelab-deploy.packages.${pkgs.system}.default ]; }; } diff --git a/hosts/ha1/configuration.nix b/hosts/ha1/configuration.nix index dcb8133..ce43676 100644 --- a/hosts/ha1/configuration.nix +++ b/hosts/ha1/configuration.nix @@ -57,6 +57,7 @@ # Vault secrets management vault.enable = true; + homelab.deploy.enable = true; vault.secrets.backup-helper = { secretPath = "shared/backup/password"; extractKey = "password"; diff --git a/hosts/http-proxy/configuration.nix b/hosts/http-proxy/configuration.nix index ab494f1..8524075 100644 --- a/hosts/http-proxy/configuration.nix +++ b/hosts/http-proxy/configuration.nix @@ -61,6 +61,7 @@ "flakes" ]; vault.enable = true; + homelab.deploy.enable = true; nix.settings.tarball-ttl = 0; environment.systemPackages = with pkgs; [ diff --git a/hosts/monitoring01/configuration.nix b/hosts/monitoring01/configuration.nix index 3a95d73..713dbf8 100644 --- a/hosts/monitoring01/configuration.nix +++ b/hosts/monitoring01/configuration.nix @@ -58,6 +58,7 @@ # Vault secrets management vault.enable = true; + homelab.deploy.enable = true; vault.secrets.backup-helper = { secretPath = "shared/backup/password"; extractKey = "password"; diff --git a/hosts/nix-cache01/configuration.nix b/hosts/nix-cache01/configuration.nix index c3192a8..46dcff1 100644 --- a/hosts/nix-cache01/configuration.nix +++ b/hosts/nix-cache01/configuration.nix @@ -55,6 +55,7 @@ "flakes" ]; vault.enable = true; + homelab.deploy.enable = true; nix.settings.tarball-ttl = 0; environment.systemPackages = with pkgs; [ diff --git a/hosts/ns1/configuration.nix b/hosts/ns1/configuration.nix index c5b9e88..aef3c38 100644 --- a/hosts/ns1/configuration.nix +++ b/hosts/ns1/configuration.nix @@ -48,6 +48,7 @@ "flakes" ]; vault.enable = true; + homelab.deploy.enable = true; homelab.host = { role = "dns"; diff --git a/hosts/ns2/configuration.nix b/hosts/ns2/configuration.nix index c49c5e5..c1baca7 100644 --- a/hosts/ns2/configuration.nix +++ b/hosts/ns2/configuration.nix @@ -48,6 +48,7 @@ "flakes" ]; vault.enable = true; + homelab.deploy.enable = true; homelab.host = { role = "dns"; diff --git a/hosts/vaulttest01/configuration.nix b/hosts/vaulttest01/configuration.nix index fd2bb57..570ca31 100644 --- a/hosts/vaulttest01/configuration.nix +++ b/hosts/vaulttest01/configuration.nix @@ -92,6 +92,7 @@ in # Testing config # Enable Vault secrets management vault.enable = true; + homelab.deploy.enable = true; # Define a test secret vault.secrets.test-service = { diff --git a/modules/homelab/default.nix b/modules/homelab/default.nix index a803d45..130c64b 100644 --- a/modules/homelab/default.nix +++ b/modules/homelab/default.nix @@ -1,6 +1,7 @@ { ... }: { imports = [ + ./deploy.nix ./dns.nix ./host.nix ./monitoring.nix diff --git a/modules/homelab/deploy.nix b/modules/homelab/deploy.nix new file mode 100644 index 0000000..38cae58 --- /dev/null +++ b/modules/homelab/deploy.nix @@ -0,0 +1,16 @@ +{ config, lib, ... }: + +{ + options.homelab.deploy = { + enable = lib.mkEnableOption "homelab-deploy listener for NATS-based deployments"; + }; + + config = { + assertions = [ + { + assertion = config.homelab.deploy.enable -> config.vault.enable; + message = "homelab.deploy.enable requires vault.enable to be true (needed for NKey secret)"; + } + ]; + }; +} diff --git a/services/nats/default.nix b/services/nats/default.nix index 20b7efa..fdb7ce3 100644 --- a/services/nats/default.nix +++ b/services/nats/default.nix @@ -1,16 +1,18 @@ { ... }: { - homelab.monitoring.scrapeTargets = [{ - job_name = "nats"; - port = 7777; - }]; + homelab.monitoring.scrapeTargets = [ + { + job_name = "nats"; + port = 7777; + } + ]; services.prometheus.exporters.nats = { enable = true; url = "http://localhost:8222"; extraFlags = [ - "-varz" # General server info - "-connz" # Connection info + "-varz" # General server info + "-connz" # Connection info "-jsz=all" # JetStream info ]; }; @@ -38,6 +40,48 @@ } ]; }; + + DEPLOY = { + users = [ + # Shared listener (all hosts use this) + { + nkey = "UCCZJSUGLCSLBBKHBPL4QA66TUMQUGIXGLIFTWDEH43MGWM3LDD232X4"; + permissions = { + subscribe = [ + "deploy.test.>" + "deploy.prod.>" + "deploy.discover" + ]; + publish = [ + "deploy.responses.>" + "deploy.discover" + ]; + }; + } + # Test deployer (MCP without admin) + { + nkey = "UBR66CX2ZNY5XNVQF5VBG4WFAF54LSGUYCUNNCEYRILDQ4NXDAD2THZU"; + permissions = { + publish = [ + "deploy.test.>" + "deploy.discover" + ]; + subscribe = [ + "deploy.responses.>" + "deploy.discover" + ]; + }; + } + # Admin deployer (full access) + { + nkey = "UD2BFB7DLM67P5UUVCKBUJMCHADIZLGGVUNSRLZE2ZC66FW2XT44P73Y"; + permissions = { + publish = [ "deploy.>" ]; + subscribe = [ "deploy.>" ]; + }; + } + ]; + }; }; system_account = "ADMIN"; jetstream = { diff --git a/system/default.nix b/system/default.nix index 7e3c80f..a4d9949 100644 --- a/system/default.nix +++ b/system/default.nix @@ -3,6 +3,7 @@ imports = [ ./acme.nix ./autoupgrade.nix + ./homelab-deploy.nix ./monitoring ./motd.nix ./packages.nix diff --git a/system/homelab-deploy.nix b/system/homelab-deploy.nix new file mode 100644 index 0000000..68edc04 --- /dev/null +++ b/system/homelab-deploy.nix @@ -0,0 +1,30 @@ +{ config, lib, ... }: + +let + hostCfg = config.homelab.host; +in +{ + config = lib.mkIf config.homelab.deploy.enable { + # Fetch listener NKey from Vault + vault.secrets.homelab-deploy-nkey = { + secretPath = "shared/homelab-deploy/listener-nkey"; + extractKey = "nkey"; + }; + + # Enable homelab-deploy listener + services.homelab-deploy.listener = { + enable = true; + tier = hostCfg.tier; + role = hostCfg.role; + natsUrl = "nats://nats1.home.2rjus.net:4222"; + nkeyFile = "/run/secrets/homelab-deploy-nkey"; + flakeUrl = "git+https://git.t-juice.club/torjus/nixos-servers.git"; + }; + + # Ensure listener starts after vault secret is available + systemd.services.homelab-deploy-listener = { + after = [ "vault-secret-homelab-deploy-nkey.service" ]; + requires = [ "vault-secret-homelab-deploy-nkey.service" ]; + }; + }; +} diff --git a/terraform/vault/approle.tf b/terraform/vault/approle.tf index 86269e6..6f2fd05 100644 --- a/terraform/vault/approle.tf +++ b/terraform/vault/approle.tf @@ -4,6 +4,17 @@ resource "vault_auth_backend" "approle" { path = "approle" } +# Shared policy for homelab-deploy (all hosts need this for NATS-based deployments) +resource "vault_policy" "homelab_deploy" { + name = "homelab-deploy" + + policy = <