variable "base_hostname" { type = string description = "Base hostname to serve content from" default = "dev.homelab" } job "traefik" { datacenters = ["dc1"] type = "service" priority = 100 constraint { attribute = "${node.class}" value = "ingress" } constraint { distinct_hosts = true } update { max_parallel = 1 # canary = 1 # auto_promote = true auto_revert = true } group "traefik" { count = 1 network { port "web" { static = 80 } port "websecure" { static = 443 } port "syslog" { static = 514 } port "metrics" { to = 8989 } } ephemeral_disk { migrate = true sticky = true } service { name = "traefik" port = "web" meta { metrics_addr = "${NOMAD_ADDR_metrics}" } check { type = "http" path = "/ping" port = "web" interval = "10s" timeout = "2s" } connect { native = true } tags = [ "traefik.enable=true", "traefik.http.routers.traefik.entryPoints=websecure", "traefik.http.routers.traefik.service=api@internal", ] } task "traefik" { driver = "docker" config { image = "traefik:2.9" ports = ["web", "websecure"] network_mode = "host" mount { type = "bind" target = "/etc/traefik" source = "local/config" } mount { type = "bind" target = "/etc/traefik/usersfile" source = "secrets/usersfile" } } vault { policies = ["access-tables", "nomad-task"] } template { # Avoid conflict with TOML lists [[ ]] and Go templates {{ }} left_delimiter = "<<" right_delimiter = ">>" data = <> certResolver = "letsEncrypt" [[entryPoints.websecure.http.tls.domains]] main = "*.<< keyOrDefault "global/base_hostname" "${var.base_hostname}" >>" << end ->> [entryPoints.metrics] address = ":8989" [entryPoints.auth] # TODO: Narrow this from all interfaces to localhost only address = ":8999" # TODO: Narrow this from insecure to possibly localhost only [entryPoints.auth.forwardedHeaders] insecure = true [entryPoints.auth.proxyProtocol] insecure = true [entryPoints.syslogtcp] address = ":514" [entryPoints.syslogudp] address = ":514/udp" [api] dashboard = true [ping] entrypoint = "web" [metrics] [metrics.prometheus] entrypoint = "metrics" # manualRouting = true [providers.file] directory = "/etc/traefik/conf" watch = true [providers.consulCatalog] connectAware = true connectByDefault = true exposedByDefault = false defaultRule = "Host(`{{normalize .Name}}.<< keyOrDefault "global/base_hostname" "${var.base_hostname}" >>`)" [providers.consulCatalog.endpoint] address = "http://<< env "CONSUL_HTTP_ADDR" >>" << if keyExists "traefik/acme/email" ->> [certificatesResolvers.letsEncrypt.acme] email = "<< key "traefik/acme/email" >>" # Store in /local because /secrets doesn't persist with ephemeral disk storage = "/local/acme.json" [certificatesResolvers.letsEncrypt.acme.dnsChallenge] provider = "cloudflare" resolvers = ["1.1.1.1:53", "8.8.8.8:53"] delayBeforeCheck = 0 << end ->> EOH destination = "local/config/traefik.toml" } template { data = <