{
  config,
  lib,
  globals,
  dns,
  ...
}: let
  kunisZone = dns.lib.toString "kun.is" (import ./kun.is.zone.nix globals dns);
in {
  options.bind9.enable = lib.mkEnableOption "bind9";

  config = lib.mkIf config.bind9.enable {
    kubernetes.resources = {
      configMaps = {
        bind9-env.data.TZ = "Europe/Amsterdam";

        bind9-config.data = {
          # TODO: this was copied from nix's generated bind config
          # Is there a way to generate this without actually running the nixos module?
          config = ''
            acl cachenetworks {  127.0.0.0/24;  };
            acl badnetworks {  };

            options {
              listen-on {  any;  };
              listen-on-v6 {  any;  };
              allow-query { cachenetworks; };
              blackhole { badnetworks; };
              forward first;
              forwarders {  };
              directory "/run/named";
              pid-file "/run/named/named.pid";
              allow-transfer { none; };
              allow-recursion { none; };
              version none;
              notify no;
            };

            zone "kun.is" {
              type master;
              file "/etc/bind/kun.is.zone";
              allow-transfer {  };
              allow-query { any; };
            };
          '';

          kunis-zone = kunisZone;
        };
      };

      deployments.bind9.spec = {
        selector.matchLabels.app = "bind9";

        template = {
          metadata.labels.app = "bind9";

          spec = {
            containers = {
              bind9-udp = {
                image = globals.images.bind9;
                envFrom = [{configMapRef.name = "bind9-env";}];

                ports.dns-udp = {
                  containerPort = 53;
                  protocol = "UDP";
                };

                volumeMounts = [
                  {
                    name = "config";
                    mountPath = "/etc/bind/named.conf";
                    subPath = "config";
                  }
                  {
                    name = "config";
                    mountPath = "/etc/bind/kun.is.zone";
                    subPath = "kunis-zone";
                  }
                ];
              };

              bind9-tcp = {
                image = globals.images.bind9;
                envFrom = [{configMapRef.name = "bind9-env";}];

                ports.dns-tcp = {
                  containerPort = 53;
                  protocol = "TCP";
                };

                volumeMounts = [
                  {
                    name = "config";
                    mountPath = "/etc/bind/named.conf";
                    subPath = "config";
                  }
                  {
                    name = "config";
                    mountPath = "/etc/bind/kun.is.zone";
                    subPath = "kunis-zone";
                  }
                ];
              };
            };

            volumes = [
              {
                name = "config";
                configMap.name = "bind9-config";
              }
            ];
          };
        };
      };

      services = {
        bind9-udp = {
          metadata.annotations = {
            "metallb.universe.tf/loadBalancerIPs" = "${globals.bind9IPv4},${globals.bind9Ipv6}";
            # "metallb.universe.tf/loadBalancerIPs" = "${globals.bind9IPv4}";
            "metallb.universe.tf/allow-shared-ip" = "dns";
          };

          spec = {
            type = "LoadBalancer";
            selector.app = "bind9";
            ipFamilies = ["IPv4" "IPv6"];
            ipFamilyPolicy = "RequireDualStack";

            ports.dns = {
              port = 53;
              targetPort = "dns-udp";
              protocol = "UDP";
            };
          };
        };

        bind9-tcp = {
          metadata.annotations = {
            "metallb.universe.tf/loadBalancerIPs" = "${globals.bind9IPv4},${globals.bind9Ipv6}";
            # "metallb.universe.tf/loadBalancerIPs" = "${globals.bind9IPv4}";
            "metallb.universe.tf/allow-shared-ip" = "dns";
          };

          spec = {
            type = "LoadBalancer";
            selector.app = "bind9";
            ipFamilies = ["IPv4" "IPv6"];
            ipFamilyPolicy = "RequireDualStack";

            ports.dns = {
              port = 53;
              targetPort = "dns-tcp";
              protocol = "TCP";
            };
          };
        };
      };
    };
  };
}