resource "docker_network" "traefik" {
  name = "traefik"
}

resource "docker_image" "traefik" {
  name = "traefik:2.9.8"
}

resource "docker_container" "traefik" {
  image      = docker_image.traefik.image_id
  name       = "traefik"
  privileged = false
  must_run   = false

  network_mode = "bridge"

  networks_advanced {
    name = docker_network.traefik.name
  }

  ports {
    internal = 80
    external = 80
    ip       = local.public_ip
  }

  ports {
    internal = 443
    external = 443
    ip       = local.public_ip
  }

  command = [
    "--log.level=DEBUG",
    "--api=true",
    "--api.dashboard=true",
    "--api.debug=true",
    #    "--api.insecure=true",
    "--providers.docker=true",
    "--providers.docker.exposedbydefault=false",
    "--entrypoints.websecure.address=:443",
    "--entrypoints.web.address=:80",
    "--entrypoints.web.http.redirections.entrypoint.to=websecure",
    "--entrypoints.web.http.redirections.entrypoint.scheme=https",
    "--certificatesresolvers.linode.acme.dnschallenge.provider=linode",
    "--certificatesresolvers.linode.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53",
    "--certificatesresolvers.linode.acme.email=root@trygvis.io",
    "--certificatesresolvers.linode.acme.storage=/letsencrypt/acme.json",

    # There doesn't seem to be a way to define a specific
    # serversTransport through the CLI or lables, to here backend
    # certificate checks are globally disabled.
    "--serverstransport.insecureskipverify",
  ]

  dynamic "labels" {
    for_each = [
      { label = "traefik.enable", value = "true" },
      { label = "traefik.http.routers.traefik.service", value = "api@internal" },
      { label = "traefik.http.routers.traefik.rule", value = "Host(`${local.host}`)" },
      { label = "traefik.http.routers.traefik.entrypoints", value = "websecure" },
      { label = "traefik.http.routers.traefik.tls.certresolver", value = "linode" },
    ]
    content {
      label = labels.value["label"]
      value = labels.value["value"]
    }
  }

  env = [
    "LINODE_TOKEN=${data.sops_file_entry.linode_token.data}"
  ]

  mounts {
    source    = "/etc/docker-service/traefik/letsencrypt"
    target    = "/letsencrypt"
    type      = "bind"
    read_only = false
  }

  mounts {
    source    = "/var/run/docker.sock"
    target    = "/var/run/docker.sock"
    type      = "bind"
    read_only = true
  }

  depends_on = [
    resource.null_resource.letsencrypt,
  ]
}

locals {
  path = "/etc/docker-service/traefik/letsencrypt"
}

resource "null_resource" "letsencrypt" {
  triggers = {
    path = local.path
  }

  provisioner "local-exec" {
    command = "ssh ${local.host} sudo mkdir -p ${local.path}"
  }
}