WIP: shared lego acme

This commit is contained in:
IamTheFij 2023-12-29 07:38:39 -08:00
parent 7bc4ae1f8b
commit f11f1f4137
6 changed files with 194 additions and 0 deletions

View File

@ -47,6 +47,12 @@ all:
group: "bin"
mode: "0755"
read_only: false
- name: certs
path: /srv/volumes/certs
mode: "0755"
owner: root
group: bin
read_only: false
pi4:
nomad_node_role: both
nomad_reserved_memory: 512

View File

@ -95,6 +95,10 @@ nomad/jobs/immich:
nomad/jobs/ipdvr/radarr:
db_pass: VALUE
db_user: VALUE
nomad/jobs/lego:
acme_email: VALUE
domain_lego_dns: VALUE
usersfile: VALUE
nomad/jobs/lidarr:
db_name: VALUE
db_pass: VALUE

44
core/acme.tf Normal file
View File

@ -0,0 +1,44 @@
module "acme" {
source = "../services/service"
name = "acme"
image = "caddy:2.7.4"
args = ["caddy", "--config", "$${NOMAD_TASK_DIR}/Caddyfile", "run"]
ingress = true
service_port = 80
use_wesher = var.use_wesher
templates = [
{
data = <<EOF
{
local_certs
debug
storage file_system {{ env "NOMAD_ALLOC_DIR" }}/data
}
:80, :443 {
tls internal
reverse_proxy "/chain" http://localhost:2019 {
header_up Host {upstream_hostport}
rewrite /pki/ca/local/certificates
}
@denied not remote_ip private_ranges
error @denied "Who dis?" 401
acme_server
}
EOF
dest = "Caddyfile"
mount = false
change_mode = "script"
change_script = {
command = "caddy"
args = ["reload", "--config", "$${NOMAD_TASK_DIR}/Caddyfle"]
}
},
]
}

98
core/lego.nomad Normal file
View File

@ -0,0 +1,98 @@
variable "lego_version" {
default = "4.14.2"
type = string
}
variable "nomad_version" {
default = "1.7.2"
type = string
}
job "lego" {
type = "batch"
periodic {
cron = "@weekly"
prohibit_overlap = true
}
group "main" {
volume "certs" {
type = "host"
read_only = true
source = "certs"
}
task "main" {
driver = "docker"
config {
image = "ubuntu:latest"
command = "sh"
args = ["${NOMAD_TASK_DIR}/start.sh"]
}
volume_mount {
volume = "certs"
destination = "/root/.lego"
read_only = true
}
artifact {
source = "https://github.com/go-acme/lego/releases/download/v${var.lego_version}/lego_v${var.lego_version}_linux_${attr.cpu.arch}.tar.gz"
}
artifact {
source = "https://releases.hashicorp.com/nomad/${var.nomad_version}/nomad_${var.nomad_version}_linux_${attr.cpu.arch}.zip"
}
template {
data = <<EOH
#! /bin/sh
ls -l ${NOMAD_TASK_DIR}
arg=run
if [ -f /root/.lego/certificates/_.thefij.rocks.crt ]; then
arg=renew
fi
${NOMAD_TASK_DIR}/lego \
--server=https://acme-staging-v02.api.letsencrypt.org/directory \
--accept-tos --pem \
--email=iamthefij@gmail.com \
--domains="*.iamthefij.com" \
--dns="cloudflare" \
$arg
# chmod +x ${NOMAD_TASK_DIR}/nomad
# ${NOMAD_TASK_DIR}/nomad var list
sleep 1000
EOH
destination = "${NOMAD_TASK_DIR}/start.sh"
}
template {
data = <<EOH
{{ with nomadVar "nomad/jobs/lego" -}}
CF_DNS_API_TOKEN={{ .domain_lego_dns }}
CF_ZONE_API_TOKEN={{ .domain_lego_dns }}
{{- end }}
EOH
destination = "secrets/cloudflare.env"
env = true
}
env = {
NOMAD_ADDR = "unix:///secrets/api.sock"
}
identity {
env = true
}
}
}
}

20
core/lego.tf Normal file
View File

@ -0,0 +1,20 @@
resource "nomad_job" "lego" {
jobspec = file("${path.module}/lego.nomad")
}
resource "nomad_acl_policy" "secrets_certs_write" {
name = "secrets-certs-write"
description = "Write certs to secrets store"
rules_hcl = <<EOH
namespace "default" {
variables {
path "secrets/certs/*" {
capabilities = ["write", "read"]
}
}
}
EOH
job_acl {
job_id = "lego/*"
}
}

View File

@ -54,6 +54,12 @@ job "traefik" {
sticky = true
}
volume "certs" {
type = "host"
read_only = true
source = "certs"
}
service {
name = "traefik"
provider = "nomad"
@ -102,6 +108,12 @@ job "traefik" {
}
}
volume_mount {
volume = "certs"
destination = "/etc/traefik/certs"
read_only = true
}
template {
# Avoid conflict with TOML lists [[ ]] and Go templates {{ }}
left_delimiter = "<<"
@ -248,6 +260,16 @@ CF_ZONE_API_TOKEN={{ .domain_lego_dns }}
change_mode = "noop"
}
template {
data = <<EOH
[[tls.certificates]]
certFile = "/etc/traefik/certs/_.thefij.rocks.crt"
keyFile = "/etc/traefik/certs/_.thefij.rocks.key"
EOH
destination = "local/config/conf/static-tls.toml"
change_mode = "noop"
}
template {
data = <<EOH
[http.middlewares]