254 lines
5.9 KiB
HCL
254 lines
5.9 KiB
HCL
# Gatus - Self-hosted Status Page
|
|
#
|
|
# Lightweight status page that monitors endpoints and displays uptime.
|
|
# Accessible at status.abaci.one
|
|
|
|
resource "kubernetes_config_map" "gatus_config" {
|
|
metadata {
|
|
name = "gatus-config"
|
|
namespace = kubernetes_namespace.abaci.metadata[0].name
|
|
}
|
|
|
|
data = {
|
|
"config.yaml" = <<-EOT
|
|
storage:
|
|
type: sqlite
|
|
path: /data/gatus.db
|
|
|
|
ui:
|
|
title: Abaci.one Status
|
|
description: Service health and uptime monitoring
|
|
header: Abaci.one
|
|
logo: ""
|
|
|
|
endpoints:
|
|
# ============ Website ============
|
|
- name: "Homepage"
|
|
group: Website
|
|
url: "https://abaci.one/"
|
|
interval: 60s
|
|
conditions:
|
|
- "[STATUS] == 200"
|
|
- "[RESPONSE_TIME] < 2000"
|
|
|
|
# ============ Arcade ============
|
|
- name: "Games Hub — /games"
|
|
group: Arcade
|
|
url: "https://abaci.one/games"
|
|
interval: 120s
|
|
conditions:
|
|
- "[STATUS] == 200"
|
|
|
|
# ============ Worksheets ============
|
|
- name: "Worksheet Builder — /create/worksheets"
|
|
group: Worksheets
|
|
url: "https://abaci.one/create/worksheets"
|
|
interval: 120s
|
|
conditions:
|
|
- "[STATUS] == 200"
|
|
|
|
- name: "Flashcard Generator — /create/flashcards"
|
|
group: Worksheets
|
|
url: "https://abaci.one/create/flashcards"
|
|
interval: 120s
|
|
conditions:
|
|
- "[STATUS] == 200"
|
|
|
|
# ============ Flowcharts ============
|
|
- name: "Flowchart Viewer — /flowchart"
|
|
group: Flowcharts
|
|
url: "https://abaci.one/flowchart"
|
|
interval: 120s
|
|
conditions:
|
|
- "[STATUS] == 200"
|
|
|
|
# ============ Core API ============
|
|
- name: "Health Check — /api/health"
|
|
group: Core API
|
|
url: "https://abaci.one/api/health"
|
|
interval: 30s
|
|
conditions:
|
|
- "[STATUS] == 200"
|
|
- "[RESPONSE_TIME] < 500"
|
|
- "[BODY].status == healthy"
|
|
|
|
# ============ Infrastructure ============
|
|
- name: "SQLite Database"
|
|
group: Infrastructure
|
|
url: "https://abaci.one/api/health"
|
|
interval: 30s
|
|
conditions:
|
|
- "[STATUS] == 200"
|
|
- "[BODY].checks.database.status == ok"
|
|
|
|
- name: "Redis Cache"
|
|
group: Infrastructure
|
|
url: "tcp://redis.abaci.svc.cluster.local:6379"
|
|
interval: 30s
|
|
conditions:
|
|
- "[CONNECTED] == true"
|
|
|
|
# ============ E2E Tests ============
|
|
- name: "Browser Smoke Tests"
|
|
group: E2E Tests
|
|
url: "https://abaci.one/api/smoke-test-status"
|
|
interval: 60s
|
|
conditions:
|
|
- "[STATUS] == 200"
|
|
- "[BODY].status == passed"
|
|
EOT
|
|
}
|
|
}
|
|
|
|
# Note: Using emptyDir for simplicity. Gatus rebuilds history on restart.
|
|
# If persistent history is needed, use a PVC but terraform may timeout
|
|
# waiting for local-path provisioner (which only binds when pod mounts).
|
|
|
|
resource "kubernetes_deployment" "gatus" {
|
|
metadata {
|
|
name = "gatus"
|
|
namespace = kubernetes_namespace.abaci.metadata[0].name
|
|
labels = {
|
|
app = "gatus"
|
|
}
|
|
}
|
|
|
|
spec {
|
|
replicas = 1
|
|
|
|
selector {
|
|
match_labels = {
|
|
app = "gatus"
|
|
}
|
|
}
|
|
|
|
template {
|
|
metadata {
|
|
labels = {
|
|
app = "gatus"
|
|
}
|
|
}
|
|
|
|
spec {
|
|
container {
|
|
name = "gatus"
|
|
image = "twinproduction/gatus:v5.11.0"
|
|
|
|
port {
|
|
container_port = 8080
|
|
}
|
|
|
|
volume_mount {
|
|
name = "config"
|
|
mount_path = "/config"
|
|
read_only = true
|
|
}
|
|
|
|
volume_mount {
|
|
name = "data"
|
|
mount_path = "/data"
|
|
}
|
|
|
|
resources {
|
|
requests = {
|
|
memory = "64Mi"
|
|
cpu = "50m"
|
|
}
|
|
limits = {
|
|
memory = "128Mi"
|
|
cpu = "200m"
|
|
}
|
|
}
|
|
|
|
liveness_probe {
|
|
http_get {
|
|
path = "/health"
|
|
port = 8080
|
|
}
|
|
initial_delay_seconds = 10
|
|
period_seconds = 30
|
|
}
|
|
|
|
readiness_probe {
|
|
http_get {
|
|
path = "/health"
|
|
port = 8080
|
|
}
|
|
initial_delay_seconds = 5
|
|
period_seconds = 10
|
|
}
|
|
}
|
|
|
|
volume {
|
|
name = "config"
|
|
config_map {
|
|
name = kubernetes_config_map.gatus_config.metadata[0].name
|
|
}
|
|
}
|
|
|
|
volume {
|
|
name = "data"
|
|
empty_dir {}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
resource "kubernetes_service" "gatus" {
|
|
metadata {
|
|
name = "gatus"
|
|
namespace = kubernetes_namespace.abaci.metadata[0].name
|
|
}
|
|
|
|
spec {
|
|
selector = {
|
|
app = "gatus"
|
|
}
|
|
|
|
port {
|
|
port = 80
|
|
target_port = 8080
|
|
}
|
|
|
|
type = "ClusterIP"
|
|
}
|
|
}
|
|
|
|
# Ingress for status.abaci.one (HTTP only for now, SSL can be added later)
|
|
# Note: ACME HTTP-01 challenge has issues with Traefik ingress routing.
|
|
# Consider DNS-01 challenge or using the main domain's wildcard cert.
|
|
resource "kubernetes_ingress_v1" "gatus" {
|
|
metadata {
|
|
name = "gatus"
|
|
namespace = kubernetes_namespace.abaci.metadata[0].name
|
|
annotations = {
|
|
"traefik.ingress.kubernetes.io/router.entrypoints" = "web,websecure"
|
|
}
|
|
}
|
|
|
|
spec {
|
|
ingress_class_name = "traefik"
|
|
|
|
rule {
|
|
host = "status.${var.app_domain}"
|
|
|
|
http {
|
|
path {
|
|
path = "/"
|
|
path_type = "Prefix"
|
|
|
|
backend {
|
|
service {
|
|
name = kubernetes_service.gatus.metadata[0].name
|
|
port {
|
|
number = 80
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|