config/roles/traefik.nix

125 lines
3.2 KiB
Nix
Raw Normal View History

2024-12-26 19:20:22 +01:00
{
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 = map (domain: {
main = domain;
sans = [ "*.${domain}" ];
}) cfg.wildcardDomains;
2024-12-26 19:20:22 +01:00
};
};
};
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
);
};
};
};
};
};
}