Sort parts of the nomad intra into folders

This should make finding things easier
This commit is contained in:
2025-10-22 22:02:25 +11:00
parent 8869bd1cb2
commit 92f60a7572
15 changed files with 176 additions and 25 deletions

View File

@@ -0,0 +1,123 @@
job "authelia" {
group "authelia" {
network {
mode = "bridge"
port "http" {
static = 9091
}
}
service {
connect {
sidecar_service {
proxy {
upstreams {
destination_name = "postgres"
local_bind_port = 5432
}
}
}
}
}
service {
name = "auth"
port = "http"
tags = [
"traefik.enable=true",
]
connect {
sidecar_service {}
}
check {
type = "http"
path = "/health"
interval = "10s"
timeout = "2s"
}
}
task "authelia" {
driver = "docker"
config {
image = "authelia/authelia:latest"
ports = ["http"]
volumes = [
"local/config:/config",
"local/data:/data" # TODO: Move this to a volume
]
}
resources {
cpu = 100
memory = 128
}
template {
data = <<EOF
server:
address: tcp://0.0.0.0:{{ env "NOMAD_PORT_http" }}/
theme: "auto"
identity_validation:
reset_password:
jwt_secret: "{{ with nomadVar "nomad/jobs/authelia" }}{{ .jwt_secret }}{{ end }}"
authentication_backend:
file:
path: /config/users_database.yml
access_control:
default_policy: deny
rules:
- domain: "*.othrayte.one"
policy: one_factor
session:
name: authelia_session
secret: "{{ with nomadVar "nomad/jobs/authelia" }}{{ .session_secret }}{{ end }}"
inactivity: '2 days and 9 hours'
expiration: '1 hour'
remember_me: '90 days'
cookies:
- domain: othrayte.one
authelia_url: "https://auth.othrayte.one"
storage:
encryption_key: "{{ with nomadVar "nomad/jobs/authelia" }}{{ .encryption_key }}{{ end }}"
postgres:
address: 'tcp://127.0.0.1:5432'
database: 'authelia'
schema: 'public'
username: 'authelia'
password: '{{ with nomadVar "nomad/jobs/authelia" }}{{ .database_pw }}{{ end }}'
timeout: '5s'
notifier:
filesystem:
filename: /config/notification.txt
EOF
destination = "local/config/configuration.yml"
}
template {
data = <<EOF
# Users database for Authelia
users:
othrayte:
password: "$2y$10$FeemMJevZXq6y1pc6FNOXeIlthGWiGHRmMfpV33BNcpChA5ozLUmK"
displayname: "Adrian"
email: "othrayte@gmail.com"
EOF
destination = "local/config/users_database.yml"
}
}
}
}

View File

@@ -0,0 +1,24 @@
resource "nomad_job" "authelia" {
jobspec = file("${path.module}/authelia.nomad.hcl")
}
resource "postgresql_role" "authelia" {
name = "authelia"
password = data.sops_file.secrets.data["authelia.database_pw"]
login = true
}
resource "postgresql_database" "authelia" {
name = "authelia"
owner = postgresql_role.authelia.name
}
resource "nomad_variable" "authelia" {
path = "nomad/jobs/authelia"
items = {
session_secret = data.sops_file.secrets.data["authelia.session_secret"]
jwt_secret = data.sops_file.secrets.data["authelia.jwt_secret"]
encryption_key = data.sops_file.secrets.data["authelia.encryption_key"]
database_pw = data.sops_file.secrets.data["authelia.database_pw"]
}
}

View File

@@ -0,0 +1,33 @@
terraform {
required_providers {
sops = {
source = "carlpett/sops"
version = "~> 0.5"
}
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 5"
}
postgresql = {
source = "cyrilgdn/postgresql"
}
}
}
provider "nomad" {
address = "http://jaglan-beta-m20.lan:4646"
}
data "sops_file" "secrets" {
source_file = "secrets/secrets.enc.json"
}
provider "cloudflare" {
api_token = data.sops_file.secrets.data["cloudflare.api_token"]
}
data "nomad_plugin" "smb" {
plugin_id = "smb"
wait_for_healthy = true
}

View File

@@ -0,0 +1,248 @@
job "traefik" {
group "traefik" {
count = 2
network {
mode = "bridge"
port "http" {
static = 80
}
port "https" {
static = 443
}
port "api" {
static = 8081
}
}
service {
connect {
sidecar_service {
proxy {
upstreams {
destination_name = "auth"
local_bind_port = 9091
}
}
}
}
}
service {
name = "traefik"
port = "api"
check {
name = "alive"
type = "tcp"
port = "api"
interval = "10s"
timeout = "2s"
}
}
task "traefik" {
driver = "docker"
config {
image = "traefik:v3.3"
ports = ["http", "https", "api"]
volumes = [
"local/traefik.yml:/etc/traefik/traefik.yml",
"local/configs/:/etc/traefik/configs/"
]
}
volume_mount {
volume = "unraid_appdata_traefik"
destination = "/opt/traefik"
read_only = false
}
template {
data = <<EOF
log:
level: INFO
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
http:
tls:
certResolver: letsencrypt
traefik:
address: ":8081"
api:
dashboard: true
insecure: true
providers:
file:
directory: "/etc/traefik/configs/"
consulCatalog:
prefix: "traefik"
exposedByDefault: false
defaultRule: {{"Host(`{{ .Name }}.othrayte.one`)"}}
endpoint:
address: "{{ env "NOMAD_HOST_IP_http" }}:8500"
scheme: "http"
certificatesResolvers:
letsencrypt:
acme:
email: "othrayte@gmail.com"
storage: "/opt/traefik/acme.json"
httpChallenge:
entryPoint: web
EOF
destination = "local/traefik.yml"
}
template {
data = <<EOF
http:
middlewares:
auth:
forwardAuth:
address: "http://localhost:9091/api/authz/forward-auth"
trustForwardHeader: true
auth-allow-token:
chain:
middlewares:
- auth
inject-kopia-basic-auth:
headers:
customRequestHeaders:
Authorization: "Basic {{ with nomadVar "nomad/jobs/traefik" }}{{ .kopia_basic_auth }}{{ end }}"
routers:
fallback:
rule: "HostRegexp(`^.+$`)"
entryPoints:
- websecure
middlewares:
- auth
service: noop@internal # This router just applies middleware
priority: 1
traefik:
rule: "Host(`traefik.othrayte.one`)"
service: traefik
middlewares:
- auth
nomad-ui:
rule: "Host(`nomad.othrayte.one`)"
service: nomad-ui
middlewares:
- auth
consul-ui:
rule: "Host(`consul.othrayte.one`)"
service: consul-ui
middlewares:
- auth
unraid:
rule: "Host(`unraid.othrayte.one`)"
service: unraid
middlewares:
- auth
frigate:
rule: "Host(`frigate.othrayte.one`)"
service: frigate
middlewares:
- auth
kopia:
rule: "Host(`kopia.othrayte.one`)"
service: kopia
middlewares:
- auth
- inject-kopia-basic-auth
hass:
rule: "Host(`hass.othrayte.one`)"
service: hass
middlewares:
- auth
hass-token:
rule: "Host(`${hass_magic_token}-hass.othrayte.one`)"
service: hass
services:
traefik:
loadBalancer:
servers:
- url: "http://localhost:8081"
nomad-ui:
loadBalancer:
servers:
- url: "http://{{ env "NOMAD_HOST_IP_http" }}:4646"
consul-ui:
loadBalancer:
servers:
- url: "http://{{ env "NOMAD_HOST_IP_http" }}:8500"
unraid:
loadBalancer:
servers:
- url: "http://192.168.1.192:80"
frigate:
loadBalancer:
servers:
- url: "http://192.168.1.192:5000"
kopia:
loadBalancer:
servers:
- url: "http://192.168.1.192:51515"
hass:
loadBalancer:
servers:
- url: "http://192.168.1.234:8123"
EOF
destination = "local/configs/nomad.yml"
}
resources {
cpu = 100
memory = 128
}
}
volume "unraid_appdata_traefik" {
type = "csi"
read_only = false
source = "unraid_appdata_traefik"
access_mode = "multi-node-multi-writer"
attachment_mode = "file-system"
mount_options {
mount_flags = ["file_mode=0600", "uid=1000", "gid=1000"]
}
}
task "cloudflared" {
driver = "docker"
config {
image = "cloudflare/cloudflared:latest"
args = [
"tunnel", "--no-autoupdate", "run"
]
}
template {
data = <<EOH
TUNNEL_TOKEN="{{ with nomadVar "nomad/jobs/traefik" }}{{ .cf_tunnel_token }}{{ end }}"
EOH
destination = "secrets/tunnel.env"
env = true # Load the file as environment variables
}
}
}
}

View File

@@ -0,0 +1,59 @@
resource "cloudflare_dns_record" "othrayte-one" {
comment = "othrayte.one proxy via cloudflared tunnel to traefik"
zone_id = "2616ab2a44d0645b03fbc3106c79bd99"
type = "CNAME"
name = "othrayte.one"
content = "59ca3eb1-5f0b-45e1-97ff-e373569c6689.cfargotunnel.com"
proxied = true
ttl = 1 # Auto
}
resource "cloudflare_dns_record" "star-othrayte-one" {
comment = "*.othrayte.one proxy via cloudflared tunnel to traefik"
zone_id = "2616ab2a44d0645b03fbc3106c79bd99"
type = "CNAME"
name = "*.othrayte.one"
content = "59ca3eb1-5f0b-45e1-97ff-e373569c6689.cfargotunnel.com"
proxied = true
ttl = 1 # Auto
}
resource "nomad_variable" "traefik" {
path = "nomad/jobs/traefik"
items = {
cf_tunnel_token = data.sops_file.secrets.data["traefik.cf_tunnel_token"]
kopia_basic_auth = data.sops_file.secrets.data["traefik.kopia_basic_auth"]
}
}
resource "nomad_job" "traefik" {
jobspec = templatefile("${path.module}/traefik.nomad.hcl", {
hass_magic_token = nonsensitive(data.sops_file.secrets.data["hass.magic-token"])
})
}
resource "nomad_csi_volume_registration" "unraid_appdata_traefik" {
#Note: Before chaning the definition of this volume you need to stop the jobs that are using it
depends_on = [data.nomad_plugin.smb]
plugin_id = "smb"
volume_id = "unraid_appdata_traefik"
name = "unraid_appdata_traefik"
external_id = "unraid_appdata_traefik"
capability {
access_mode = "multi-node-multi-writer"
attachment_mode = "file-system"
}
context = {
source = "//192.168.1.192/appdata"
subDir = "traefik" # Note: Needs to be manually created on the share
}
secrets = {
"username" = "nomad"
"password" = data.sops_file.secrets.data["unraid.nomad"]
}
}