From 16396b5459bfc6215c71ae539bd3817b8cd4e2c7 Mon Sep 17 00:00:00 2001 From: Kalle Struik Date: Thu, 26 Dec 2024 19:20:22 +0100 Subject: [PATCH] Add traefik role --- flake.nix | 6 ++- hosts.nix | 11 ++++ roles/default.nix | 1 + roles/sonarr.nix | 1 - roles/traefik.nix | 126 ++++++++++++++++++++++++++++++++++++++++++++++ utils.nix | 9 +++- 6 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 roles/traefik.nix diff --git a/flake.nix b/flake.nix index ef5f2a3..3422c5e 100644 --- a/flake.nix +++ b/flake.nix @@ -18,7 +18,11 @@ in { nixosConfigurations = nixpkgs.lib.mapAttrs ( - hostname: value: (utils.mkSystem (value // { inherit hostname; })) + hostname: value: + (utils.mkSystem { + inherit hosts; + hostConfig = (value // { inherit hostname; }); + }) ) hosts; }; } diff --git a/hosts.nix b/hosts.nix index b670336..eac7a93 100644 --- a/hosts.nix +++ b/hosts.nix @@ -15,6 +15,7 @@ in nix-test = { roles = with roles; [ + traefik sonarr ]; config = { @@ -22,4 +23,14 @@ in }; stateVersion = "24.05"; }; + + nix-test2 = { + roles = with roles; [ + sonarr + ]; + config = { + sonarr.domain = "sonarr2.${hlConfig.domain}"; + }; + stateVersion = "24.05"; + }; } diff --git a/roles/default.nix b/roles/default.nix index 5f6a13a..4a921ec 100644 --- a/roles/default.nix +++ b/roles/default.nix @@ -3,4 +3,5 @@ }: { sonarr = utils.mkRole (import ./sonarr.nix); + traefik = utils.mkRole (import ./traefik.nix); } diff --git a/roles/sonarr.nix b/roles/sonarr.nix index fef33c8..6d19d77 100644 --- a/roles/sonarr.nix +++ b/roles/sonarr.nix @@ -15,7 +15,6 @@ name = "${hostname}-sonarr"; rule = "Host(`${config.sonarr.domain}`)"; target = "http://${hostname}.lan:8989"; - } ]; diff --git a/roles/traefik.nix b/roles/traefik.nix new file mode 100644 index 0000000..238e8bf --- /dev/null +++ b/roles/traefik.nix @@ -0,0 +1,126 @@ +{ + name = "Traefik"; + description = '' + Runs the Traefik reverse proxy. + ''; + + nixosModule = + { + lib, + pkgs, + config, + hosts, + ... + }: + with lib; + { + options.traefik = { + wildcardDomains = mkOption { + type = types.listOf types.str; + default = [ ]; + }; + }; + + config = + let + cfg = config.traefik; + routes = concatMap ( + hostname: + concatMap ( + role: + role.traefikRoutes { + inherit hostname; + config = hosts.${hostname}.config; + } + ) hosts.${hostname}.roles + ) (builtins.attrNames hosts); + in + { + sops.secrets = { + "traefik.acmeEmail" = { + owner = "traefik"; + format = "dotenv"; + }; + "traefik.CLOUDFLARE_EMAIL" = { + owner = "traefik"; + format = "dotenv"; + }; + "traefik.CLOUDFLARE_DNS_API_TOKEN" = { + owner = "traefik"; + format = "dotenv"; + }; + }; + + services.traefik = { + enable = true; + environmentFiles = [ + config.sops.secrets."traefik.acmeEmail".path + config.sops.secrets."traefik.CLOUDFLARE_EMAIL".path + config.sops.secrets."traefik.CLOUDFLARE_DNS_API_TOKEN".path + ]; + + staticConfiguration = { + entryPoints = { + web = { + address = ":80"; + + http = { + redirections = { + entryPoint = { + to = "websecure"; + scheme = "https"; + }; + }; + }; + }; + + websecure = { + address = ":443"; + + tls = { + certResolver = "letsencrypt"; + domains = mkList ( + map (domain: { + main = domain; + sans = [ "*.${domain}" ]; + }) cfg.wildcardDomains + ); + }; + }; + }; + + certificatesResolvers = { + letsencrypt = { + acme = { + email = "$acmeEmail"; + storage = "acme.json"; + dnsChallenge = { + provider = "cloudflare"; + }; + }; + }; + }; + + http = { + routers = listToAttrs ( + map (route: { + name = route.name; + value = { + entrypoints = [ "websecure" ]; + service = route.name; + rule = route.rule; + }; + }) routes + ); + services = listToAttrs ( + map (route: { + name = route.name; + value.loadBalancer.servers.url = [ route.target ]; + }) routes + ); + }; + }; + }; + }; + }; +} diff --git a/utils.nix b/utils.nix index fcf98e1..fb8a4cc 100644 --- a/utils.nix +++ b/utils.nix @@ -6,11 +6,16 @@ }: { mkSystem = - hostConfig: + { hostConfig, hosts }: nixpkgs.lib.nixosSystem { system = "x86_64-linux"; specialArgs = { - inherit inputs outputs hostConfig; + inherit + inputs + outputs + hostConfig + hosts + ; }; modules = [ inputs.impermanence.nixosModules.impermanence