Restructure: servers/legion/ layout, rename repo to infrastructure

This commit is contained in:
Will Anderson
2026-03-23 07:38:42 -05:00
parent 7751eddd73
commit 0b4a236a88
22 changed files with 4 additions and 4 deletions
+288
View File
@@ -0,0 +1,288 @@
# Monitoring stack — Prometheus, Grafana, Loki, Tempo, Alloy, Alertmanager
# Grafana UI: https://grafana.nook.family (admin / var.grafana_admin_password)
#
# TODO: Migrate Tempo to tempo-distributed once R2 is wired as trace storage backend
# TODO: Replace loki.useTestSchema=true with proper schema_config for production
resource "kubernetes_namespace" "monitoring" {
metadata {
name = "monitoring"
labels = {
managed-by = "terraform"
tier = "observability"
}
}
}
# kube-prometheus-stack — Prometheus, Grafana, Alertmanager, node exporters
resource "helm_release" "kube_prometheus_stack" {
name = "kube-prometheus-stack"
namespace = kubernetes_namespace.monitoring.metadata[0].name
repository = "https://prometheus-community.github.io/helm-charts"
chart = "kube-prometheus-stack"
timeout = 600
# Grafana
set {
name = "grafana.adminPassword"
value = var.grafana_admin_password
}
set {
name = "grafana.persistence.enabled"
value = "true"
}
set {
name = "grafana.persistence.size"
value = "5Gi"
}
set {
name = "grafana.sidecar.datasources.defaultDatasourceEnabled"
value = "false"
}
set {
name = "grafana.initChownData.enabled"
value = "false"
}
set {
name = "grafana.ingress.enabled"
value = "true"
}
set {
name = "grafana.ingress.ingressClassName"
value = "traefik"
}
set {
name = "grafana.ingress.hosts[0]"
value = "grafana.${var.infra_domain}"
}
set {
name = "grafana.ingress.tls[0].secretName"
value = "grafana-tls"
}
set {
name = "grafana.ingress.tls[0].hosts[0]"
value = "grafana.${var.infra_domain}"
}
set {
name = "grafana.ingress.annotations.traefik\\.ingress\\.kubernetes\\.io/router\\.entrypoints"
value = "websecure"
}
set {
name = "grafana.ingress.annotations.cert-manager\\.io/cluster-issuer"
value = "letsencrypt-prod"
}
# Prometheus persistent storage
set {
name = "prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage"
value = "20Gi"
}
# Disable k3s-incompatible scrapers
set {
name = "kubeEtcd.enabled"
value = "false"
}
set {
name = "kubeControllerManager.enabled"
value = "false"
}
set {
name = "kubeScheduler.enabled"
value = "false"
}
set {
name = "kubeProxy.enabled"
value = "false"
}
depends_on = [helm_release.cert_manager]
}
# Grafana extra datasources — Loki and Tempo wired up with cross-linking
resource "kubernetes_config_map" "grafana_extra_datasources" {
metadata {
name = "grafana-extra-datasources"
namespace = kubernetes_namespace.monitoring.metadata[0].name
labels = { grafana_datasource = "1" }
}
data = {
"datasources.yaml" = <<-EOT
apiVersion: 1
datasources:
- name: Loki
type: loki
uid: loki
url: http://loki-gateway.monitoring.svc.cluster.local
access: proxy
jsonData:
httpHeaderName1: X-Scope-OrgID
secureJsonData:
httpHeaderValue1: legion
- name: Tempo
type: tempo
uid: tempo
url: http://tempo.monitoring.svc.cluster.local:3100
access: proxy
jsonData:
lokiSearch:
datasourceUid: loki
tracesToLogsV2:
datasourceUid: loki
filterByTraceID: true
filterBySpanID: false
tracesToMetrics:
datasourceUid: prometheus
EOT
}
depends_on = [helm_release.kube_prometheus_stack]
}
# Loki — log aggregation (single binary mode)
# TODO: Replace useTestSchema with proper schema_config before storing long-term logs
resource "helm_release" "loki" {
name = "loki"
namespace = kubernetes_namespace.monitoring.metadata[0].name
repository = "https://grafana.github.io/helm-charts"
chart = "loki"
timeout = 300
set {
name = "loki.commonConfig.replication_factor"
value = "1"
}
set {
name = "loki.storage.type"
value = "filesystem"
}
set {
name = "loki.useTestSchema"
value = "true"
}
set {
name = "singleBinary.replicas"
value = "1"
}
set {
name = "singleBinary.persistence.enabled"
value = "true"
}
set {
name = "singleBinary.persistence.size"
value = "10Gi"
}
set {
name = "deploymentMode"
value = "SingleBinary"
}
set {
name = "backend.replicas"
value = "0"
}
set {
name = "read.replicas"
value = "0"
}
set {
name = "write.replicas"
value = "0"
}
set {
name = "chunksCache.enabled"
value = "false"
}
set {
name = "resultsCache.enabled"
value = "false"
}
}
# Tempo — distributed tracing backend (local storage)
# TODO: Migrate to tempo-distributed with R2 storage once R2 trace bucket is created
resource "helm_release" "tempo" {
name = "tempo"
namespace = kubernetes_namespace.monitoring.metadata[0].name
repository = "https://grafana.github.io/helm-charts"
chart = "tempo"
timeout = 300
set {
name = "tempo.storage.trace.backend"
value = "local"
}
set {
name = "tempo.storage.trace.local.path"
value = "/var/tempo"
}
set {
name = "persistence.enabled"
value = "true"
}
set {
name = "persistence.size"
value = "10Gi"
}
}
# Alloy — log shipping + OTLP trace forwarding (replaces deprecated Promtail)
resource "helm_release" "alloy" {
name = "alloy"
namespace = kubernetes_namespace.monitoring.metadata[0].name
repository = "https://grafana.github.io/helm-charts"
chart = "alloy"
timeout = 300
set {
name = "controller.type"
value = "daemonset"
}
values = [<<-EOT
alloy:
configMap:
content: |
discovery.kubernetes "pods" {
role = "pod"
}
discovery.relabel "pods" {
targets = discovery.kubernetes.pods.targets
rule { source_labels = ["__meta_kubernetes_namespace"]; target_label = "namespace" }
rule { source_labels = ["__meta_kubernetes_pod_name"]; target_label = "pod" }
rule { source_labels = ["__meta_kubernetes_pod_container_name"]; target_label = "container" }
rule { source_labels = ["__meta_kubernetes_pod_label_app"]; target_label = "app" }
}
loki.source.kubernetes "pods" {
targets = discovery.relabel.pods.output
forward_to = [loki.write.default.receiver]
}
loki.write "default" {
endpoint {
url = "http://loki-gateway.monitoring.svc.cluster.local/loki/api/v1/push"
tenant_id = "legion"
}
}
otelcol.receiver.otlp "default" {
grpc { endpoint = "0.0.0.0:4317" }
http { endpoint = "0.0.0.0:4318" }
output {
traces = [otelcol.exporter.otlp.tempo.input]
}
}
otelcol.exporter.otlp "tempo" {
client {
endpoint = "tempo.monitoring.svc.cluster.local:4317"
tls { insecure = true }
}
}
EOT
]
depends_on = [helm_release.loki, helm_release.tempo]
}