feat(vaultwarden): add SMTP configuration options and enhance signup settings
- Introduced SMTP settings for Vaultwarden including host, port, security, and authentication details. - Added variables for signup verification, 2FA settings, password hints, and logging options. - Updated Vaultwarden deployment to utilize new SMTP configurations. - Enhanced Grafana module to support dynamic dashboard and datasource provisioning. - Added LLM proxy configuration for Open Web UI with necessary environment variables.
This commit is contained in:
@@ -3,7 +3,7 @@ module "open-webui" {
|
||||
|
||||
persistent_folder = local.persistent_folder
|
||||
fqdn = local.open_webui_fqdn
|
||||
ollama_proxy = local.ollama_proxy
|
||||
llm_proxy = local.llm_proxy
|
||||
secret_key = var.webui_secret_key
|
||||
tag = "v0.9.2-slim"
|
||||
log_level = local.open_webui_log_level
|
||||
@@ -43,13 +43,13 @@ module "nextcloud" {
|
||||
issuer = local.internal_issuer
|
||||
}
|
||||
|
||||
module "comfyui_proxy" {
|
||||
source = "../../modules/utils/wol_proxy"
|
||||
# module "comfyui_proxy" {
|
||||
# source = "../../modules/utils/wol_proxy"
|
||||
|
||||
upstream = local.comfyui_proxy
|
||||
proxy_port = local.comfyui_proxy.port
|
||||
namespace = "comfyui"
|
||||
}
|
||||
# upstream = local.comfyui_proxy
|
||||
# proxy_port = local.comfyui_proxy.port
|
||||
# namespace = "comfyui"
|
||||
# }
|
||||
|
||||
module "prometheus" {
|
||||
source = "../../modules/utils/prometheus"
|
||||
@@ -73,6 +73,15 @@ module "grafana" {
|
||||
|
||||
persistent_folder = "${local.persistent_folder}/monitoring"
|
||||
fqdn = local.grafana_fqdn
|
||||
dashboard_folder = {
|
||||
System = "${path.module}/resources/grafana/system"
|
||||
Kubernetes = "${path.module}/resources/grafana/kubernetes"
|
||||
Security = "${path.module}/resources/grafana/security"
|
||||
GPU = "${path.module}/resources/grafana/gpu"
|
||||
LLM = "${path.module}/resources/grafana/llm"
|
||||
Windows = "${path.module}/resources/grafana/windows"
|
||||
}
|
||||
datasource_folder = "${path.module}/resources/grafana"
|
||||
}
|
||||
|
||||
module "mstream" {
|
||||
@@ -99,6 +108,16 @@ module "vaultwarden" {
|
||||
persistent_folder = local.vaultwarden_folder
|
||||
fqdn = local.vaultwarden_fqdn
|
||||
issuer = local.vaultwarden_issuer
|
||||
tag = "1.33.4"
|
||||
tag = local.vaultwarden_version
|
||||
admin_token = var.vaultwarden_admin_token
|
||||
smtp_host = local.vaultwarden_smtp_host
|
||||
smtp_port = local.vaultwarden_smtp_port
|
||||
smtp_security = local.vaultwarden_smtp_security
|
||||
smtp_from = local.vaultwarden_smtp_from
|
||||
smtp_from_name = local.vaultwarden_smtp_from_name
|
||||
smtp_username = local.vaultwarden_smtp_username
|
||||
|
||||
# We temporarily enable signup to create the first admin user, then we will disable it and rotate the admin token
|
||||
# signup_enabled = true
|
||||
# signup_verify = false
|
||||
}
|
||||
|
||||
@@ -132,22 +132,22 @@ locals {
|
||||
]
|
||||
|
||||
proxy_services = {
|
||||
"comfyui" = {
|
||||
http_port = 8080
|
||||
https_port = 8443
|
||||
tls = true
|
||||
fqdn = ["comfyui.lab.alexpires.me"]
|
||||
upstream = "http://upstream.comfyui.svc.cluster.local:8188"
|
||||
resolver = "kube-dns.kube-system.svc.cluster.local"
|
||||
# "comfyui" = {
|
||||
# http_port = 8080
|
||||
# https_port = 8443
|
||||
# tls = true
|
||||
# fqdn = ["comfyui.lab.alexpires.me"]
|
||||
# upstream = "http://upstream.comfyui.svc.cluster.local:8188"
|
||||
# resolver = "kube-dns.kube-system.svc.cluster.local"
|
||||
|
||||
locations = [
|
||||
{
|
||||
path = "/"
|
||||
"Upgrade" = "$http_upgrade"
|
||||
"Connection" = "upgrade"
|
||||
},
|
||||
]
|
||||
}
|
||||
# locations = [
|
||||
# {
|
||||
# path = "/"
|
||||
# "Upgrade" = "$http_upgrade"
|
||||
# "Connection" = "upgrade"
|
||||
# },
|
||||
# ]
|
||||
# }
|
||||
}
|
||||
|
||||
streams = {
|
||||
@@ -171,20 +171,20 @@ locals {
|
||||
}
|
||||
}
|
||||
|
||||
ollama_proxy = {
|
||||
llm_proxy = {
|
||||
enabled = true
|
||||
mac = "04:7c:16:d6:63:66"
|
||||
ip = "10.19.4.106"
|
||||
port = "11435"
|
||||
port = 11434
|
||||
scheme = "http"
|
||||
}
|
||||
|
||||
comfyui_proxy = {
|
||||
mac = "04:7c:16:d6:63:66"
|
||||
ip = "10.19.4.106"
|
||||
port = "8188"
|
||||
scheme = "http"
|
||||
}
|
||||
# comfyui_proxy = {
|
||||
# mac = "04:7c:16:d6:63:66"
|
||||
# ip = "10.19.4.106"
|
||||
# port = "8188"
|
||||
# scheme = "http"
|
||||
# }
|
||||
|
||||
scaleway_smtp_host = "smtp.tem.scw.cloud"
|
||||
|
||||
@@ -235,16 +235,16 @@ locals {
|
||||
|
||||
grafana_fqdn = "grafana.${local.lab_domain}"
|
||||
|
||||
devolo_devices = {
|
||||
devolo_620 = {
|
||||
ip = "192.168.0.199"
|
||||
model = "620"
|
||||
}
|
||||
# devolo_326 = {
|
||||
# ip = "192.168.0.200"
|
||||
# model = "326"
|
||||
# }
|
||||
}
|
||||
# devolo_devices = {
|
||||
# devolo_620 = {
|
||||
# ip = "192.168.0.199"
|
||||
# model = "620"
|
||||
# }
|
||||
# # devolo_326 = {
|
||||
# # ip = "192.168.0.200"
|
||||
# # model = "326"
|
||||
# # }
|
||||
# }
|
||||
|
||||
# mstream
|
||||
mstream_music_folder = "/mnt/storage/Music"
|
||||
@@ -256,9 +256,17 @@ locals {
|
||||
searxng_issuer = "letsencrypt-prod"
|
||||
|
||||
# vaultwarden
|
||||
vaultwarden_folder = "/mnt/md0/vaultwarden"
|
||||
vaultwarden_fqdn = "vaultwarden.${local.lab_domain}"
|
||||
vaultwarden_issuer = "internal-ca"
|
||||
vaultwarden_folder = "/mnt/md0/vaultwarden"
|
||||
vaultwarden_fqdn = "vaultwarden.${local.lab_domain}"
|
||||
vaultwarden_issuer = "letsencrypt-prod"
|
||||
vaultwarden_version = "1.36.0"
|
||||
vaultwarden_smtp_host = local.scaleway_smtp_host
|
||||
vaultwarden_smtp_port = 465
|
||||
vaultwarden_smtp_security = "force_tls"
|
||||
vaultwarden_smtp_from = "vaultwarden@${local.lab_domain}"
|
||||
vaultwarden_smtp_from_name = "Vaultwarden"
|
||||
vaultwarden_smtp_username = var.scaleway_project_id
|
||||
vaultwarden_smtp_password = local.mail_app_api_secret_key
|
||||
}
|
||||
|
||||
data "terraform_remote_state" "scaleway" {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
- name: prometheus-dev-01
|
||||
type: prometheus
|
||||
url: http://prometheus.prometheus.svc.cluster.local:9090
|
||||
isDefault: true
|
||||
editable: false
|
||||
jsonData:
|
||||
httpMethod: POST
|
||||
timeInterval: 15s
|
||||
- name: prometheus-ci-01
|
||||
type: prometheus
|
||||
url: http://ci-01.lab.alexpires.me:9090
|
||||
isDefault: false
|
||||
editable: false
|
||||
jsonData:
|
||||
httpMethod: POST
|
||||
timeInterval: 15s
|
||||
- name: prometheus-gpu-01
|
||||
type: prometheus
|
||||
url: http://gpu-01.lab.alexpires.me:9091
|
||||
isDefault: false
|
||||
editable: false
|
||||
jsonData:
|
||||
httpMethod: POST
|
||||
timeInterval: 15s
|
||||
- name: prometheus-prod-01
|
||||
type: prometheus
|
||||
url: http://10.5.5.2:9090
|
||||
isDefault: false
|
||||
editable: false
|
||||
jsonData:
|
||||
httpMethod: POST
|
||||
timeInterval: 15s
|
||||
@@ -0,0 +1,500 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "-- Grafana --"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"id": null,
|
||||
"links": [],
|
||||
"liveNow": true,
|
||||
"panels": [
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "red",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "green",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 6,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 1,
|
||||
"options": {
|
||||
"colorMode": "background",
|
||||
"graphMode": "none",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "auto"
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "up{job=~\"prometheus|nvidia-gpu|amdgpu_exporter\"}",
|
||||
"instant": true,
|
||||
"legendFormat": "{{job}}",
|
||||
"range": false,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "GPU Exporter Health",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "percent"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 6
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_gpu_util_percent|gpu_util_percent\"}",
|
||||
"legendFormat": "{{__name__}} {{gpu}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "GPU Utilization",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "celsius"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 6
|
||||
},
|
||||
"id": 3,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_temperature_celsius|temperature_celsius\"}",
|
||||
"legendFormat": "{{__name__}} {{gpu}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "GPU Temperature",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "watt"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 14
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_power_watts|power_watts\"}",
|
||||
"legendFormat": "{{__name__}} {{gpu}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "GPU Power Draw",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "percent"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 14
|
||||
},
|
||||
"id": 5,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_memory_used_percent\"}",
|
||||
"legendFormat": "nvidia",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "100 * mem_used_bytes / clamp_min(mem_used_bytes + mem_avail_bytes, 1)",
|
||||
"legendFormat": "amd {{gpu}}",
|
||||
"range": true,
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"title": "GPU Memory Usage",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "s"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 22
|
||||
},
|
||||
"id": 6,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "scrape_duration_seconds{job=~\"nvidia-gpu|amdgpu_exporter|prometheus\"}",
|
||||
"legendFormat": "{{job}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "GPU Scrape Duration",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 22
|
||||
},
|
||||
"id": 7,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_pstate\"}",
|
||||
"legendFormat": "{{__name__}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "NVIDIA P-State",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 30
|
||||
},
|
||||
"id": 8,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_pcie_link_gen_current\"}",
|
||||
"legendFormat": "pcie gen",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_pcie_link_width_current\"}",
|
||||
"legendFormat": "pcie width",
|
||||
"range": true,
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"title": "NVIDIA PCIe Link",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"max": 1,
|
||||
"min": 0,
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 30
|
||||
},
|
||||
"id": 9,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_throttle_sw_power_cap\"}",
|
||||
"legendFormat": "sw power cap",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_throttle_hw_thermal_slowdown\"}",
|
||||
"legendFormat": "hw thermal slowdown",
|
||||
"range": true,
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_throttle_hw_power_brake_slowdown\"}",
|
||||
"legendFormat": "hw power brake slowdown",
|
||||
"range": true,
|
||||
"refId": "C"
|
||||
}
|
||||
],
|
||||
"title": "NVIDIA Throttle Flags",
|
||||
"type": "timeseries"
|
||||
}
|
||||
],
|
||||
"refresh": "5s",
|
||||
"schemaVersion": 39,
|
||||
"style": "dark",
|
||||
"tags": [
|
||||
"gpu",
|
||||
"monitoring",
|
||||
"realtime"
|
||||
],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"current": {
|
||||
"selected": true,
|
||||
"text": "Prometheus",
|
||||
"value": "Prometheus"
|
||||
},
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": "Datasource",
|
||||
"multi": false,
|
||||
"name": "datasource",
|
||||
"options": [],
|
||||
"query": "prometheus",
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"type": "datasource"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-30m",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "GPU Monitoring Realtime",
|
||||
"uid": "gpu-monitoring-realtime",
|
||||
"version": 2,
|
||||
"weekStart": ""
|
||||
}
|
||||
@@ -0,0 +1,436 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "-- Grafana --"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"id": null,
|
||||
"links": [],
|
||||
"liveNow": true,
|
||||
"panels": [
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "red",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "green",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 6,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 1,
|
||||
"options": {
|
||||
"colorMode": "background",
|
||||
"graphMode": "none",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "auto"
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "up{job=~\"prometheus|llama_exporter\"}",
|
||||
"instant": true,
|
||||
"legendFormat": "{{job}}",
|
||||
"range": false,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "LLM Exporter Health",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 6
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "llama_server_health{model=~\"$model\"}",
|
||||
"legendFormat": "health {{server}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "llama_models_loaded{model=~\"$model\"}",
|
||||
"legendFormat": "models {{server}} {{model}}",
|
||||
"range": true,
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"title": "Llama Server Metrics",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "reqps"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 6
|
||||
},
|
||||
"id": 3,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "rate(llamacpp:tokens_predicted_total{model=~\"$model\"}[5m])",
|
||||
"legendFormat": "decode {{model}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "rate(llamacpp:prompt_tokens_total{model=~\"$model\"}[5m])",
|
||||
"legendFormat": "prompt {{model}}",
|
||||
"range": true,
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"title": "Token Throughput",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "s"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 14
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "rate(llamacpp:tokens_predicted_seconds_total{model=~\"$model\"}[5m])",
|
||||
"legendFormat": "decode time {{model}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "rate(llamacpp:prompt_seconds_total{model=~\"$model\"}[5m])",
|
||||
"legendFormat": "prompt time {{model}}",
|
||||
"range": true,
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"title": "Processing Time",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 14
|
||||
},
|
||||
"id": 5,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "llamacpp:requests_processing{model=~\"$model\"}",
|
||||
"legendFormat": "processing {{model}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "llamacpp:requests_deferred{model=~\"$model\"}",
|
||||
"legendFormat": "deferred {{model}}",
|
||||
"range": true,
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"title": "Request Queue",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 22
|
||||
},
|
||||
"id": 6,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "llamacpp:n_busy_slots_per_decode{model=~\"$model\"}",
|
||||
"legendFormat": "busy slots {{model}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Busy Slots Per Decode",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 22
|
||||
},
|
||||
"id": 7,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "llamacpp:n_tokens_max{model=~\"$model\"}",
|
||||
"legendFormat": "max tokens {{model}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Max Tokens (Context Window)",
|
||||
"type": "timeseries"
|
||||
}
|
||||
],
|
||||
"refresh": "5s",
|
||||
"schemaVersion": 39,
|
||||
"style": "dark",
|
||||
"tags": [
|
||||
"llm",
|
||||
"monitoring",
|
||||
"realtime"
|
||||
],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"current": {
|
||||
"selected": true,
|
||||
"text": "Prometheus",
|
||||
"value": "Prometheus"
|
||||
},
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": "Datasource",
|
||||
"multi": false,
|
||||
"name": "datasource",
|
||||
"options": [],
|
||||
"query": "prometheus",
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"type": "datasource"
|
||||
},
|
||||
{
|
||||
"current": {
|
||||
"selected": false,
|
||||
"text": "All",
|
||||
"value": "$__all"
|
||||
},
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "$datasource"
|
||||
},
|
||||
"definition": "label_values(llamacpp:tokens_predicted_total, model)",
|
||||
"hide": 0,
|
||||
"includeAll": true,
|
||||
"label": "Model",
|
||||
"multi": false,
|
||||
"name": "model",
|
||||
"options": [],
|
||||
"query": "label_values(llamacpp:tokens_predicted_total, model)",
|
||||
"refresh": 2,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"sort": 1,
|
||||
"type": "query"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-30m",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "LLM Monitoring Realtime",
|
||||
"uid": "llm-monitoring-realtime",
|
||||
"version": 1,
|
||||
"weekStart": ""
|
||||
}
|
||||
@@ -39,3 +39,4 @@ variable "vaultwarden_admin_token" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
|
||||
@@ -161,9 +161,20 @@ module "auth_exporter" {
|
||||
module "vaultwarden" {
|
||||
source = "../../modules/apps/vaultwarden"
|
||||
|
||||
persistent_folder = local.vaultwarden_folder
|
||||
fqdn = local.vaultwarden_fqdn
|
||||
issuer = local.internal_issuer
|
||||
tag = "1.33.4"
|
||||
admin_token = var.vaultwarden_admin_token
|
||||
persistent_folder = local.vaultwarden_folder
|
||||
fqdn = local.vaultwarden_fqdn
|
||||
issuer = local.vaultwarden_issuer
|
||||
tag = local.vaultwarden_version
|
||||
admin_token = var.vaultwarden_admin_token
|
||||
smtp_host = local.vaultwarden_smtp_host
|
||||
smtp_port = local.vaultwarden_smtp_port
|
||||
smtp_security = local.vaultwarden_smtp_security
|
||||
smtp_from = local.vaultwarden_smtp_from
|
||||
smtp_from_name = local.vaultwarden_smtp_from_name
|
||||
smtp_username = local.vaultwarden_smtp_username
|
||||
smtp_password = var.vaultwarden_smtp_password
|
||||
smtp_timeout = local.vaultwarden_smtp_timeout
|
||||
smtp_auth_mechanism = local.vaultwarden_smtp_auth_mechanism
|
||||
smtp_helo_name = local.vaultwarden_smtp_helo_name
|
||||
smtp_embed_images = local.vaultwarden_smtp_embed_images
|
||||
}
|
||||
|
||||
@@ -211,9 +211,20 @@ locals {
|
||||
telegram_message = file("${path.module}/resources/telegram.tpl")
|
||||
|
||||
# vaultwarden
|
||||
vaultwarden_folder = "${local.persistent_folder}/vaultwarden"
|
||||
vaultwarden_fqdn = "vaultwarden.${local.primary_domain}"
|
||||
internal_issuer = "internal-ca"
|
||||
vaultwarden_folder = "${local.persistent_folder}/vaultwarden"
|
||||
vaultwarden_fqdn = "vaultwarden.${local.primary_domain}"
|
||||
vaultwarden_issuer = "internal-ca"
|
||||
vaultwarden_version = "1.36.0"
|
||||
vaultwarden_smtp_host = ""
|
||||
vaultwarden_smtp_port = 587
|
||||
vaultwarden_smtp_security = "starttls"
|
||||
vaultwarden_smtp_from = ""
|
||||
vaultwarden_smtp_from_name = "Vaultwarden"
|
||||
vaultwarden_smtp_username = ""
|
||||
vaultwarden_smtp_timeout = 15
|
||||
vaultwarden_smtp_auth_mechanism = ""
|
||||
vaultwarden_smtp_helo_name = ""
|
||||
vaultwarden_smtp_embed_images = true
|
||||
|
||||
# get secrets from remote state
|
||||
backup_bucket_name = data.terraform_remote_state.scaleway.outputs.backup_bucket_name
|
||||
|
||||
@@ -140,3 +140,10 @@ variable "vaultwarden_admin_token" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "vaultwarden_smtp_password" {
|
||||
description = "SMTP password for VaultWarden email"
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
}
|
||||
|
||||
@@ -34,3 +34,4 @@ TF_VAR_wireguard_1_pre_shared_key=$WIREGUARD_1_PRE_SHARED_KEY
|
||||
TF_VAR_nginx_token_bearer=$NGINX_TOKEN_BEARER
|
||||
TF_VAR_telegram_bot_token=$TELEGRAM_BOT_TOKEN
|
||||
TF_VAR_vaultwarden_admin_token=$VAULTWARDEN_ADMIN_TOKEN
|
||||
TF_VAR_vaultwarden_smtp_password=$VAULTWARDEN_SMTP_PASSWORD
|
||||
|
||||
@@ -2,8 +2,47 @@ locals {
|
||||
app_version = var.tag
|
||||
monitoring_folder = "${var.persistent_folder}/grafana"
|
||||
|
||||
grafana_datasource_config = file("${path.module}/resources/default.yml")
|
||||
grafana_dashboard_provider = file("${path.module}/resources/dashboard-provider.yml")
|
||||
grafana_trivy_dashboard = file("${path.module}/resources/trivy-vulnerabilities-dashboard.json")
|
||||
grafana_gpu_realtime_dashboard = file("${path.module}/resources/gpu-realtime-dashboard.json")
|
||||
dashboard_resource_names = {
|
||||
for folder_name in keys(var.dashboard_folder) :
|
||||
folder_name => "${substr(replace(lower(folder_name), "/[^a-z0-9-]/", "-"), 0, 40)}-${substr(md5(folder_name), 0, 8)}"
|
||||
}
|
||||
|
||||
dashboard_mount_paths = {
|
||||
for folder_name in keys(var.dashboard_folder) :
|
||||
folder_name => "/var/lib/grafana/dashboards/${local.dashboard_resource_names[folder_name]}"
|
||||
}
|
||||
|
||||
# Load datasource YAMLs from app root if datasource_folder is provided
|
||||
datasource_files = {
|
||||
for f in fileset(var.datasource_folder, "*.{yml,yaml}") : f => file("${var.datasource_folder}/${f}")
|
||||
}
|
||||
|
||||
# Load dashboard JSONs from app root folders grouped by Grafana category name
|
||||
dashboard_files_by_category = {
|
||||
for folder_name, folder_path in var.dashboard_folder :
|
||||
folder_name => {
|
||||
for f in fileset(folder_path, "*.json") : f => file("${folder_path}/${f}")
|
||||
}
|
||||
}
|
||||
|
||||
grafana_dashboard_provider = yamlencode({
|
||||
apiVersion = 1
|
||||
providers = [
|
||||
for folder_name in keys(var.dashboard_folder) : {
|
||||
name = "local-${local.dashboard_resource_names[folder_name]}"
|
||||
orgId = 1
|
||||
folder = folder_name
|
||||
type = "file"
|
||||
disableDeletion = false
|
||||
updateIntervalSeconds = 30
|
||||
allowUiUpdates = true
|
||||
options = {
|
||||
path = local.dashboard_mount_paths[folder_name]
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
checksum_datasources = md5(join("", values(local.datasource_files)))
|
||||
checksum_dashboards = md5("${local.grafana_dashboard_provider}${jsonencode(local.dashboard_files_by_category)}")
|
||||
}
|
||||
|
||||
@@ -4,9 +4,7 @@ resource "kubernetes_config_map" "grafana_datasources" {
|
||||
namespace = kubernetes_namespace.grafana.metadata[0].name
|
||||
}
|
||||
|
||||
data = {
|
||||
"default.yml" = replace(local.grafana_datasource_config, "__PROMETHEUS_URL__", var.prometheus_url)
|
||||
}
|
||||
data = local.datasource_files
|
||||
}
|
||||
|
||||
resource "kubernetes_config_map" "grafana_dashboard_provider" {
|
||||
@@ -21,15 +19,14 @@ resource "kubernetes_config_map" "grafana_dashboard_provider" {
|
||||
}
|
||||
|
||||
resource "kubernetes_config_map" "grafana_dashboards" {
|
||||
for_each = local.dashboard_files_by_category
|
||||
|
||||
metadata {
|
||||
name = "grafana-dashboards"
|
||||
name = "grafana-dashboards-${local.dashboard_resource_names[each.key]}"
|
||||
namespace = kubernetes_namespace.grafana.metadata[0].name
|
||||
}
|
||||
|
||||
data = {
|
||||
"trivy-vulnerabilities-dashboard.json" = local.grafana_trivy_dashboard
|
||||
"gpu-realtime-dashboard.json" = local.grafana_gpu_realtime_dashboard
|
||||
}
|
||||
data = each.value
|
||||
}
|
||||
|
||||
resource "kubernetes_deployment" "grafana" {
|
||||
@@ -50,7 +47,9 @@ resource "kubernetes_deployment" "grafana" {
|
||||
template {
|
||||
metadata {
|
||||
labels = {
|
||||
app = "grafana"
|
||||
app = "grafana"
|
||||
checksum_datasources = local.checksum_datasources
|
||||
checksum_dashboards = local.checksum_dashboards
|
||||
}
|
||||
}
|
||||
spec {
|
||||
@@ -111,10 +110,13 @@ resource "kubernetes_deployment" "grafana" {
|
||||
mount_path = "/etc/grafana/provisioning/dashboards"
|
||||
read_only = true
|
||||
}
|
||||
volume_mount {
|
||||
name = "grafana-dashboards"
|
||||
mount_path = "/var/lib/grafana/dashboards"
|
||||
read_only = true
|
||||
dynamic "volume_mount" {
|
||||
for_each = local.dashboard_mount_paths
|
||||
content {
|
||||
name = "grafana-dashboards-${local.dashboard_resource_names[volume_mount.key]}"
|
||||
mount_path = volume_mount.value
|
||||
read_only = true
|
||||
}
|
||||
}
|
||||
}
|
||||
volume {
|
||||
@@ -135,10 +137,13 @@ resource "kubernetes_deployment" "grafana" {
|
||||
name = kubernetes_config_map.grafana_dashboard_provider.metadata[0].name
|
||||
}
|
||||
}
|
||||
volume {
|
||||
name = "grafana-dashboards"
|
||||
config_map {
|
||||
name = kubernetes_config_map.grafana_dashboards.metadata[0].name
|
||||
dynamic "volume" {
|
||||
for_each = local.dashboard_mount_paths
|
||||
content {
|
||||
name = "grafana-dashboards-${local.dashboard_resource_names[volume.key]}"
|
||||
config_map {
|
||||
name = kubernetes_config_map.grafana_dashboards[volume.key].metadata[0].name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
apiVersion: 1
|
||||
|
||||
providers:
|
||||
- name: trivy-vulnerabilities
|
||||
- name: local
|
||||
orgId: 1
|
||||
folder: Security
|
||||
folder: Default
|
||||
type: file
|
||||
disableDeletion: false
|
||||
updateIntervalSeconds: 30
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
- name: Prometheus
|
||||
type: prometheus
|
||||
access: proxy
|
||||
url: __PROMETHEUS_URL__
|
||||
isDefault: true
|
||||
editable: true
|
||||
@@ -1,550 +0,0 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "-- Grafana --"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"id": null,
|
||||
"links": [],
|
||||
"liveNow": true,
|
||||
"panels": [
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "red",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "green",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 6,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 1,
|
||||
"options": {
|
||||
"colorMode": "background",
|
||||
"graphMode": "none",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "auto"
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "up{job=~\"prometheus|nvidia-gpu|amdgpu_exporter|llama_exporter\"}",
|
||||
"instant": true,
|
||||
"legendFormat": "{{job}}",
|
||||
"range": false,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Exporter Health",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "percent"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 6
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_gpu_util_percent|gpu_util_percent\"}",
|
||||
"legendFormat": "{{__name__}} {{gpu}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "GPU Utilization",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "celsius"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 6
|
||||
},
|
||||
"id": 3,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_temperature_celsius|temperature_celsius\"}",
|
||||
"legendFormat": "{{__name__}} {{gpu}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "GPU Temperature",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "watt"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 14
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_power_watts|power_watts\"}",
|
||||
"legendFormat": "{{__name__}} {{gpu}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "GPU Power Draw",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "percent"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 14
|
||||
},
|
||||
"id": 5,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_memory_used_percent\"}",
|
||||
"legendFormat": "nvidia",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "100 * mem_used_bytes / clamp_min(mem_used_bytes + mem_avail_bytes, 1)",
|
||||
"legendFormat": "amd {{gpu}}",
|
||||
"range": true,
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"title": "GPU Memory Usage",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "s"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 22
|
||||
},
|
||||
"id": 6,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "scrape_duration_seconds{job=~\"nvidia-gpu|amdgpu_exporter|llama_exporter|prometheus\"}",
|
||||
"legendFormat": "{{job}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Scrape Duration",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 22
|
||||
},
|
||||
"id": 7,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "llama_server_health",
|
||||
"legendFormat": "health {{server}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "llama_models_loaded",
|
||||
"legendFormat": "models {{server}} {{model}}",
|
||||
"range": true,
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"title": "Llama Server Metrics",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 30
|
||||
},
|
||||
"id": 8,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_pstate\"}",
|
||||
"legendFormat": "{{__name__}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "NVIDIA P-State",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 30
|
||||
},
|
||||
"id": 9,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_pcie_link_gen_current\"}",
|
||||
"legendFormat": "pcie gen",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_pcie_link_width_current\"}",
|
||||
"legendFormat": "pcie width",
|
||||
"range": true,
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"title": "NVIDIA PCIe Link",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"max": 1,
|
||||
"min": 0,
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 38
|
||||
},
|
||||
"id": 10,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "11.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_throttle_sw_power_cap\"}",
|
||||
"legendFormat": "sw power cap",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_throttle_hw_thermal_slowdown\"}",
|
||||
"legendFormat": "hw thermal slowdown",
|
||||
"range": true,
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"editorMode": "code",
|
||||
"expr": "{__name__=~\"gpu_.*_throttle_hw_power_brake_slowdown\"}",
|
||||
"legendFormat": "hw power brake slowdown",
|
||||
"range": true,
|
||||
"refId": "C"
|
||||
}
|
||||
],
|
||||
"title": "NVIDIA Throttle Flags",
|
||||
"type": "timeseries"
|
||||
}
|
||||
],
|
||||
"refresh": "5s",
|
||||
"schemaVersion": 39,
|
||||
"style": "dark",
|
||||
"tags": [
|
||||
"gpu",
|
||||
"monitoring",
|
||||
"realtime"
|
||||
],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"current": {
|
||||
"selected": true,
|
||||
"text": "Prometheus",
|
||||
"value": "Prometheus"
|
||||
},
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": "Datasource",
|
||||
"multi": false,
|
||||
"name": "datasource",
|
||||
"options": [],
|
||||
"query": "prometheus",
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"type": "datasource"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-30m",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "GPU Monitoring Realtime",
|
||||
"uid": "gpu-monitoring-realtime",
|
||||
"version": 1,
|
||||
"weekStart": ""
|
||||
}
|
||||
@@ -21,8 +21,13 @@ variable "persistent_folder" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "prometheus_url" {
|
||||
description = "Prometheus service URL used by Grafana datasource provisioning"
|
||||
type = string
|
||||
default = "http://prometheus.prometheus.svc.cluster.local:9090"
|
||||
variable "dashboard_folder" {
|
||||
description = "Map of Grafana folder name => local folder path containing dashboard JSON files. Each entry becomes a Grafana provider/category and loads all .json files from its path."
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "datasource_folder" {
|
||||
description = "Path to a folder containing Grafana datasource provisioning YAML files. When set, all .yml/.yaml files in this folder will be loaded and have __PROMETHEUS_URL__ replaced with the actual prometheus_url. If not set, falls back to the default single-prometheus datasource."
|
||||
type = string
|
||||
}
|
||||
|
||||
+16
-16
@@ -1,22 +1,22 @@
|
||||
resource "kubernetes_service_account" "ollama_proxy" {
|
||||
resource "kubernetes_service_account" "llm_proxy" {
|
||||
|
||||
count = var.ollama_proxy.enabled ? 1 : 0
|
||||
count = var.llm_proxy.enabled ? 1 : 0
|
||||
metadata {
|
||||
name = "ollama-proxy-sa"
|
||||
name = "llm-proxy-sa"
|
||||
namespace = kubernetes_namespace.openwebui.metadata[0].name
|
||||
}
|
||||
|
||||
automount_service_account_token = false
|
||||
}
|
||||
|
||||
resource "kubernetes_deployment" "ollama_proxy" {
|
||||
resource "kubernetes_deployment" "llm_proxy" {
|
||||
|
||||
count = var.ollama_proxy.enabled ? 1 : 0
|
||||
count = var.llm_proxy.enabled ? 1 : 0
|
||||
metadata {
|
||||
name = "ollama-proxy"
|
||||
name = "llm-proxy"
|
||||
namespace = kubernetes_namespace.openwebui.metadata[0].name
|
||||
labels = {
|
||||
app = "ollama-proxy"
|
||||
app = "llm-proxy"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ resource "kubernetes_deployment" "ollama_proxy" {
|
||||
replicas = 1
|
||||
selector {
|
||||
match_labels = {
|
||||
app = "ollama-proxy"
|
||||
app = "llm-proxy"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ resource "kubernetes_deployment" "ollama_proxy" {
|
||||
template {
|
||||
metadata {
|
||||
labels = {
|
||||
app = "ollama-proxy"
|
||||
app = "llm-proxy"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,37 +57,37 @@ resource "kubernetes_deployment" "ollama_proxy" {
|
||||
|
||||
port {
|
||||
name = "http"
|
||||
container_port = var.ollama_proxy.port
|
||||
container_port = var.llm_proxy.port
|
||||
}
|
||||
|
||||
env {
|
||||
name = "UPSTREAM_MAC"
|
||||
value = var.ollama_proxy.mac
|
||||
value = var.llm_proxy.mac
|
||||
}
|
||||
|
||||
env {
|
||||
name = "UPSTREAM_IP"
|
||||
value = var.ollama_proxy.ip
|
||||
value = var.llm_proxy.ip
|
||||
}
|
||||
|
||||
env {
|
||||
name = "UPSTREAM_PORT"
|
||||
value = var.ollama_proxy.port
|
||||
value = try(var.llm_proxy.upstream_port, var.llm_proxy.port)
|
||||
}
|
||||
|
||||
env {
|
||||
name = "UPSTREAM_SCHEME"
|
||||
value = var.ollama_proxy.scheme
|
||||
value = var.llm_proxy.scheme
|
||||
}
|
||||
|
||||
env {
|
||||
name = "PROXY_PORT"
|
||||
value = var.ollama_proxy.port
|
||||
value = var.llm_proxy.port
|
||||
}
|
||||
|
||||
readiness_probe {
|
||||
tcp_socket {
|
||||
port = 11434
|
||||
port = var.llm_proxy.port
|
||||
}
|
||||
initial_delay_seconds = 5
|
||||
period_seconds = 10
|
||||
@@ -20,14 +20,15 @@ variable "issuer" {
|
||||
default = "internal-ca"
|
||||
}
|
||||
|
||||
variable "ollama_proxy" {
|
||||
description = "Configuration for the Ollama proxy"
|
||||
variable "llm_proxy" {
|
||||
description = "Configuration for the llm proxy"
|
||||
type = object({
|
||||
enabled = bool
|
||||
mac = optional(string, "")
|
||||
ip = optional(string, "")
|
||||
port = optional(string, "11434")
|
||||
scheme = optional(string, "http")
|
||||
enabled = bool
|
||||
mac = optional(string, "")
|
||||
ip = optional(string, "")
|
||||
port = optional(string, "11434")
|
||||
scheme = optional(string, "http")
|
||||
upstream_port = optional(string, "11434")
|
||||
})
|
||||
default = {
|
||||
enabled = false
|
||||
@@ -54,3 +55,9 @@ variable "log_level" {
|
||||
error_message = "log_level must be one of: DEBUG, INFO, WARNING, ERROR, CRITICAL"
|
||||
}
|
||||
}
|
||||
|
||||
variable "aiohttp_client_timeout" {
|
||||
description = "The timeout for aiohttp client in seconds (e.g., 300, 600 etc.) (By default the timeout will be set to None, effectively disabling the timeout and allowing the client to wait indefinitely.)"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
@@ -77,7 +77,6 @@ resource "kubernetes_deployment" "openwebui" {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
container {
|
||||
name = "app"
|
||||
image = "ghcr.io/open-webui/open-webui:${var.tag}"
|
||||
@@ -115,6 +114,10 @@ resource "kubernetes_deployment" "openwebui" {
|
||||
value = var.log_level
|
||||
}
|
||||
|
||||
env {
|
||||
name = "AIOHTTP_CLIENT_TIMEOUT"
|
||||
value = var.aiohttp_client_timeout
|
||||
}
|
||||
|
||||
readiness_probe {
|
||||
tcp_socket {
|
||||
|
||||
@@ -1,6 +1,23 @@
|
||||
locals {
|
||||
app_folder = var.persistent_folder
|
||||
app_version = var.tag
|
||||
app_fqdn = var.fqdn
|
||||
db_path = var.db_folder != "" ? var.db_folder : local.app_folder
|
||||
app_folder = var.persistent_folder
|
||||
app_version = var.tag
|
||||
app_fqdn = var.fqdn
|
||||
db_path = var.db_folder != "" ? var.db_folder : local.app_folder
|
||||
signup = var.signup_enabled ? "true" : "false"
|
||||
signup_verify = var.signup_verify ? "true" : "false"
|
||||
disable_2fa_remember = var.disable_2fa_remember ? "true" : "false"
|
||||
show_password_hint = var.show_password_hint ? "true" : "false"
|
||||
password_hints_allowed = var.password_hints_allowed ? "true" : "false"
|
||||
disable_icon_download = var.disable_icon_download ? "true" : "false"
|
||||
icon_service = var.icon_service
|
||||
http_request_block_non_global_ips = var.http_request_block_non_global_ips ? "true" : "false"
|
||||
extended_logging = var.extended_logging ? "true" : "false"
|
||||
websocket_enabled = var.websocket_enabled ? "true" : "false"
|
||||
sends_allowed = var.sends_allowed ? "true" : "false"
|
||||
trash_auto_delete_days = var.trash_auto_delete_days
|
||||
events_days_retain = var.events_days_retain
|
||||
admin_session_lifetime = tostring(var.admin_session_lifetime)
|
||||
|
||||
# SMTP locals — only enable mail if host or from is configured
|
||||
smtp_enabled = var.smtp_host != "" || var.smtp_from != ""
|
||||
}
|
||||
|
||||
@@ -19,11 +19,38 @@ resource "kubernetes_config_map" "vaultwarden_config" {
|
||||
namespace = kubernetes_namespace.vaultwarden.metadata[0].name
|
||||
}
|
||||
|
||||
data = {
|
||||
DOMAIN = "https://${local.app_fqdn}/"
|
||||
SIGNUP = var.signup_enabled ? "true" : "false"
|
||||
DATABASE_URL = "file:///data/db.sqlite3"
|
||||
}
|
||||
data = merge({
|
||||
DOMAIN = "https://${local.app_fqdn}/"
|
||||
SIGNUPS_ALLOWED = local.signup
|
||||
SIGNUPS_VERIFY = local.signup_verify
|
||||
DATABASE_URL = "/data/db.sqlite3"
|
||||
ENABLE_WEBSOCKET = local.websocket_enabled
|
||||
DISABLE_2FA_REMEMBER = local.disable_2fa_remember
|
||||
SHOW_PASSWORD_HINT = local.show_password_hint
|
||||
PASSWORD_HINTS_ALLOWED = local.password_hints_allowed
|
||||
DISABLE_ICON_DOWNLOAD = local.disable_icon_download
|
||||
ICON_SERVICE = local.icon_service
|
||||
HTTP_REQUEST_BLOCK_NON_GLOBAL_IPS = local.http_request_block_non_global_ips
|
||||
EXTENDED_LOGGING = local.extended_logging
|
||||
SENDS_ALLOWED = local.sends_allowed
|
||||
TRASH_AUTO_DELETE_DAYS = local.trash_auto_delete_days
|
||||
EVENTS_DAYS_RETAIN = local.events_days_retain
|
||||
ADMIN_SESSION_LIFETIME = local.admin_session_lifetime
|
||||
USE_SENDMAIL = "false"
|
||||
},
|
||||
local.smtp_enabled ? {
|
||||
SMTP_HOST = var.smtp_host
|
||||
SMTP_PORT = tostring(var.smtp_port)
|
||||
SMTP_SECURITY = var.smtp_security
|
||||
SMTP_FROM = var.smtp_from
|
||||
SMTP_FROM_NAME = var.smtp_from_name
|
||||
SMTP_TIMEOUT = tostring(var.smtp_timeout)
|
||||
SMTP_EMBED_IMAGES = var.smtp_embed_images ? "true" : "false"
|
||||
SMTP_DEBUG = var.smtp_debug ? "true" : "false"
|
||||
SMTP_ACCEPT_INVALID_CERTS = var.smtp_accept_invalid_certs ? "true" : "false"
|
||||
SMTP_ACCEPT_INVALID_HOSTNAMES = var.smtp_accept_invalid_hostnames ? "true" : "false"
|
||||
} : {}
|
||||
)
|
||||
}
|
||||
|
||||
resource "kubernetes_secret" "vaultwarden_secrets" {
|
||||
@@ -32,9 +59,14 @@ resource "kubernetes_secret" "vaultwarden_secrets" {
|
||||
namespace = kubernetes_namespace.vaultwarden.metadata[0].name
|
||||
}
|
||||
|
||||
data = {
|
||||
data = merge({
|
||||
ADMIN_TOKEN = var.admin_token
|
||||
}
|
||||
},
|
||||
local.smtp_enabled ? {
|
||||
SMTP_USERNAME = var.smtp_username
|
||||
SMTP_PASSWORD = var.smtp_password
|
||||
} : {}
|
||||
)
|
||||
}
|
||||
|
||||
resource "kubernetes_deployment" "vaultwarden" {
|
||||
@@ -62,7 +94,8 @@ resource "kubernetes_deployment" "vaultwarden" {
|
||||
template {
|
||||
metadata {
|
||||
labels = {
|
||||
app = "vaultwarden"
|
||||
app = "vaultwarden"
|
||||
config_checksum = md5(join("", values(kubernetes_config_map.vaultwarden_config.data)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +134,11 @@ resource "kubernetes_deployment" "vaultwarden" {
|
||||
}
|
||||
}
|
||||
|
||||
env {
|
||||
name = "ROCKET_PORT"
|
||||
value = "8080"
|
||||
}
|
||||
|
||||
security_context {
|
||||
allow_privilege_escalation = false
|
||||
privileged = false
|
||||
@@ -114,7 +152,7 @@ resource "kubernetes_deployment" "vaultwarden" {
|
||||
|
||||
port {
|
||||
name = "http"
|
||||
container_port = 80
|
||||
container_port = 8080
|
||||
protocol = "TCP"
|
||||
}
|
||||
|
||||
@@ -151,6 +189,7 @@ resource "kubernetes_deployment" "vaultwarden" {
|
||||
name = "vaultwarden-data"
|
||||
host_path {
|
||||
path = local.db_path
|
||||
type = "DirectoryOrCreate"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +216,7 @@ resource "kubernetes_service" "vaultwarden" {
|
||||
port {
|
||||
name = "http"
|
||||
port = 80
|
||||
target_port = 80
|
||||
target_port = 8080
|
||||
}
|
||||
|
||||
type = "ClusterIP"
|
||||
|
||||
@@ -32,6 +32,84 @@ variable "signup_enabled" {
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "signup_verify" {
|
||||
description = "Require email verification on signup (defense-in-depth)"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "disable_2fa_remember" {
|
||||
description = "Force 2FA on every login, no 'remember this browser'"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "show_password_hint" {
|
||||
description = "Show password hints on web login (no SMTP configured)"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "password_hints_allowed" {
|
||||
description = "Allow users to set password hints"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "disable_icon_download" {
|
||||
description = "Disable external icon downloads to prevent network leaks"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "icon_service" {
|
||||
description = "Icon service to use (internal, bitwarden, duckduckgo, google)"
|
||||
type = string
|
||||
default = "internal"
|
||||
}
|
||||
|
||||
variable "http_request_block_non_global_ips" {
|
||||
description = "Block requests to private/reserved IP addresses"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "extended_logging" {
|
||||
description = "Enable extended logging with timestamps for audit"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "websocket_enabled" {
|
||||
description = "Enable WebSocket notifications for real-time sync"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "sends_allowed" {
|
||||
description = "Allow users to create Bitwarden Sends"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "trash_auto_delete_days" {
|
||||
description = "Days before auto-deleting trashed items (empty = never)"
|
||||
type = string
|
||||
default = "30"
|
||||
}
|
||||
|
||||
variable "events_days_retain" {
|
||||
description = "Days to retain event logs (empty = indefinitely)"
|
||||
type = string
|
||||
default = "90"
|
||||
}
|
||||
|
||||
variable "admin_session_lifetime" {
|
||||
description = "Admin session lifetime in minutes"
|
||||
type = number
|
||||
default = 20
|
||||
}
|
||||
|
||||
variable "admin_token" {
|
||||
description = "Admin token for VaultWarden"
|
||||
type = string
|
||||
@@ -43,3 +121,90 @@ variable "db_folder" {
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
# --- SMTP / Email settings ---
|
||||
|
||||
variable "smtp_host" {
|
||||
description = "SMTP host for sending emails"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "smtp_port" {
|
||||
description = "SMTP port (default: 587 for starttls, 465 for force_tls, 25 for off)"
|
||||
type = number
|
||||
default = 587
|
||||
}
|
||||
|
||||
variable "smtp_security" {
|
||||
description = "SMTP security mode: starttls, force_tls, or off"
|
||||
type = string
|
||||
default = "starttls"
|
||||
}
|
||||
|
||||
variable "smtp_from" {
|
||||
description = "Email address to send from"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "smtp_from_name" {
|
||||
description = "Sender name for outgoing emails"
|
||||
type = string
|
||||
default = "Vaultwarden"
|
||||
}
|
||||
|
||||
variable "smtp_username" {
|
||||
description = "SMTP username for authentication"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "smtp_password" {
|
||||
description = "SMTP password for authentication"
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "smtp_timeout" {
|
||||
description = "SMTP connection timeout in seconds"
|
||||
type = number
|
||||
default = 15
|
||||
}
|
||||
|
||||
variable "smtp_auth_mechanism" {
|
||||
description = "SMTP authentication mechanisms (e.g., Plain, Login, Xoauth2, comma-separated)"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "smtp_helo_name" {
|
||||
description = "Server name sent during SMTP HELO"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "smtp_embed_images" {
|
||||
description = "Embed images as email attachments"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "smtp_debug" {
|
||||
description = "Enable detailed SMTP debug output (warning: may contain sensitive data)"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "smtp_accept_invalid_certs" {
|
||||
description = "Accept invalid SMTP server certificates (dangerous, not recommended)"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "smtp_accept_invalid_hostnames" {
|
||||
description = "Accept invalid SMTP server hostnames (dangerous, not recommended)"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user