250 lines
5.6 KiB
HCL
250 lines
5.6 KiB
HCL
variable "consul_address" {
|
|
type = string
|
|
description = "Full address of Consul instance to get catalog from"
|
|
default = "http://127.0.0.1:5400"
|
|
}
|
|
|
|
variable "base_hostname" {
|
|
type = string
|
|
description = "Base hostname to serve content from"
|
|
default = "dev.homelab"
|
|
}
|
|
|
|
job "traefik" {
|
|
datacenters = ["dc1"]
|
|
type = "system"
|
|
priority = 100
|
|
|
|
constraint {
|
|
attribute = "${node.class}"
|
|
value = "ingress"
|
|
}
|
|
|
|
update {
|
|
max_parallel = 1
|
|
auto_revert = true
|
|
}
|
|
|
|
group "traefik" {
|
|
|
|
network {
|
|
port "web" {
|
|
static = 80
|
|
}
|
|
port "websecure" {
|
|
static = 443
|
|
}
|
|
}
|
|
|
|
ephemeral_disk {
|
|
migrate = true
|
|
sticky = true
|
|
}
|
|
|
|
service {
|
|
name = "traefik"
|
|
port = "web"
|
|
|
|
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.6"
|
|
|
|
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 = <<EOH
|
|
[log]
|
|
level = "DEBUG"
|
|
|
|
[entryPoints]
|
|
[entryPoints.web]
|
|
address = ":80"
|
|
[entryPoints.web.http]
|
|
[entryPoints.web.http.redirections]
|
|
[entryPoints.web.http.redirections.entrypoint]
|
|
to = "websecure"
|
|
scheme = "https"
|
|
|
|
[entryPoints.websecure]
|
|
address = ":443"
|
|
[entryPoints.websecure.http.tls]
|
|
<< if keyExists "traefik/acme/email" ->>
|
|
certResolver = "letsEncrypt"
|
|
<< end ->>
|
|
|
|
[entryPoints.metrics]
|
|
address = ":8989"
|
|
|
|
[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" >>"
|
|
storage = "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 = <<EOH
|
|
{{ with secret "kv/data/cloudflare" }}
|
|
CF_DNS_API_TOKEN={{ .Data.data.api_token_dns_edit }}
|
|
CF_ZONE_API_TOKEN={{ .Data.data.api_token_zone_read }}
|
|
{{ end }}
|
|
EOH
|
|
destination = "secrets/cloudflare.env"
|
|
env = true
|
|
}
|
|
|
|
template {
|
|
data = <<EOH
|
|
[http]
|
|
[http.routers]
|
|
[http.routers.nomad]
|
|
entryPoints = ["websecure"]
|
|
# middlewares = []
|
|
service = "nomad"
|
|
rule = "Host(`nomad.{{ keyOrDefault "global/base_hostname" "${var.base_hostname}" }}`)"
|
|
[http.routers.consul]
|
|
entryPoints = ["websecure"]
|
|
# middlewares = []
|
|
service = "consul"
|
|
rule = "Host(`consul.{{ keyOrDefault "global/base_hostname" "${var.base_hostname}" }}`)"
|
|
[http.routers.vault]
|
|
entryPoints = ["websecure"]
|
|
# middlewares = []
|
|
service = "vault"
|
|
rule = "Host(`vault.{{ keyOrDefault "global/base_hostname" "${var.base_hostname}" }}`)"
|
|
|
|
[http.services]
|
|
{{ with service "nomad-client" -}}
|
|
[http.services.nomad]
|
|
[http.services.nomad.loadBalancer]
|
|
{{ range . -}}
|
|
[[http.services.nomad.loadBalancer.servers]]
|
|
url = "http://{{ .Address }}:{{ .Port }}"
|
|
{{ end }}
|
|
{{- end }}
|
|
{{ with service "consul" -}}
|
|
[http.services.consul]
|
|
[http.services.consul.loadBalancer]
|
|
{{ range . -}}
|
|
[[http.services.consul.loadBalancer.servers]]
|
|
# Not using .Port because that's an RPC port
|
|
url = "http://{{ .Address }}:8500"
|
|
{{ end }}
|
|
{{- end }}
|
|
{{ with service "vault" -}}
|
|
[http.services.vault]
|
|
[http.services.vault.loadBalancer]
|
|
{{ range . -}}
|
|
[[http.services.vault.loadBalancer.servers]]
|
|
url = "http://{{ .Address }}:{{ .Port }}"
|
|
{{ end }}
|
|
{{- end }}
|
|
EOH
|
|
destination = "local/config/conf/route-hashi.toml"
|
|
change_mode = "noop"
|
|
}
|
|
|
|
template {
|
|
data = <<EOH
|
|
[http.middlewares]
|
|
{{ with secret "kv/data/traefik" }}
|
|
{{ if .Data.data.usersfile }}
|
|
[http.middlewares.basic-auth.basicAuth]
|
|
usersFile = "/etc/traefik/usersfile"
|
|
{{ end }}
|
|
{{ end }}
|
|
EOH
|
|
destination = "local/config/conf/middlewares.toml"
|
|
change_mode = "noop"
|
|
}
|
|
|
|
template {
|
|
data = <<EOH
|
|
{{ with secret "kv/data/traefik" }}
|
|
{{ .Data.data.usersfile }}
|
|
{{ end }}
|
|
EOH
|
|
destination = "secrets/usersfile"
|
|
change_mode = "noop"
|
|
}
|
|
|
|
resources {
|
|
cpu = 100
|
|
memory = 100
|
|
memory_max = 500
|
|
}
|
|
}
|
|
}
|
|
}
|