Files
home-docker/terraform/logging.tf
T
2025-08-09 21:48:04 +10:00

317 lines
7.8 KiB
Terraform

resource "kubernetes_namespace" "logging" {
metadata {
name = "logging"
}
}
# Install Loki for log aggregation
resource "helm_release" "loki" {
name = "loki"
repository = "https://grafana.github.io/helm-charts"
chart = "loki"
version = "5.36.1"
namespace = kubernetes_namespace.logging.metadata[0].name
create_namespace = false
values = [
<<-EOT
deploymentMode: SingleBinary
loki:
commonConfig:
replication_factor: 1
storage:
type: 'filesystem'
filesystem:
chunks_directory: /var/loki/chunks
rules_directory: /var/loki/rules
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9095
ingester:
lifecycler:
address: 127.0.0.1
ring:
kvstore:
store: inmemory
replication_factor: 1
final_sleep: 0s
chunk_idle_period: 5m
chunk_retain_period: 30s
schema_config:
configs:
- from: 2024-01-01
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
limits_config:
retention_period: 24h
enforce_metric_name: false
reject_old_samples: true
reject_old_samples_max_age: 168h
max_cache_freshness_per_query: 10m
split_queries_by_interval: 15m
per_stream_rate_limit: 512M
per_stream_rate_limit_burst: 1024M
ingestion_rate_mb: 512
ingestion_burst_size_mb: 1024
max_streams_per_user: 0
max_line_size: 256000
singleBinary:
replicas: 1
persistence:
enabled: true
size: 10Gi
extraEnv:
- name: JAEGER_AGENT_HOST
value: ""
test:
enabled: false
monitoring:
serviceMonitor:
enabled: false
selfMonitoring:
enabled: false
grafanaAgent:
installOperator: false
lokiCanary:
enabled: false
gateway:
enabled: false
EOT
]
}
# Install Promtail for log collection
resource "helm_release" "promtail" {
name = "promtail"
repository = "https://grafana.github.io/helm-charts"
chart = "promtail"
version = "6.15.3"
namespace = kubernetes_namespace.logging.metadata[0].name
values = [
<<-EOT
config:
clients:
- url: http://loki:3100/loki/api/v1/push
scrapeConfigs:
- job_name: nginx-ingress
kubernetes_sd_configs:
- role: pod
namespaces:
names:
- ingress-nginx
pipeline_stages:
- regex:
expression: '^(?P<remote_addr>[^\s]+)\s+-\s+(?P<remote_user>[^\s]+)\s+\[(?P<time_local>[^\]]+)\]\s+"(?P<method>[^\s]+)\s+(?P<request>[^\s]+)\s+(?P<protocol>[^"]+)"\s+(?P<status>[^\s]+)\s+(?P<body_bytes_sent>[^\s]+)\s+"(?P<http_referer>[^"]*)"\s+"(?P<http_user_agent>[^"]*)"\s+(?P<request_length>[^\s]+)\s+(?P<request_time>[^\s]+)\s+\[(?P<proxy_upstream_name>[^\]]*)\]\s+\[(?P<proxy_alternative_upstream_name>[^\]]*)\]\s+(?P<upstream_addr>[^\s]+)\s+(?P<upstream_response_length>[^\s]+)\s+(?P<upstream_response_time>[^\s]+)\s+(?P<upstream_status>[^\s]+)\s+(?P<req_id>[^\s]+)'
- labels:
remote_addr: remote_addr
method: method
status: status
upstream_addr: upstream_addr
- output:
source: remote_addr
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_name]
target_label: app
regex: ingress-nginx
- source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_component]
target_label: component
regex: controller
- source_labels: [__meta_kubernetes_pod_container_name]
target_label: container
regex: controller
- source_labels: [__meta_kubernetes_namespace]
target_label: namespace
- source_labels: [__meta_kubernetes_pod_name]
target_label: pod
EOT
]
depends_on = [helm_release.loki]
}
# Install Pushgateway for custom metrics
resource "helm_release" "prometheus_pushgateway" {
name = "prometheus-pushgateway"
repository = "https://prometheus-community.github.io/helm-charts"
chart = "prometheus-pushgateway"
version = "2.4.2"
namespace = "prometheus"
set {
name = "serviceMonitor.enabled"
value = "true"
}
set {
name = "serviceMonitor.additionalLabels.release"
value = "prometheus"
}
}
# GeoIP Enricher ConfigMap
resource "kubernetes_config_map" "geoip_enricher_code" {
metadata {
name = "geoip-enricher-code"
namespace = kubernetes_namespace.logging.metadata[0].name
}
data = {
"enricher.py" = file("${path.module}/scripts/enricher.py")
"requirements.txt" = <<-EOT
requests==2.31.0
prometheus-client==0.19.0
EOT
}
}
# GeoIP Enricher Deployment
resource "kubernetes_deployment" "geoip_enricher" {
metadata {
name = "geoip-enricher"
namespace = kubernetes_namespace.logging.metadata[0].name
labels = {
app = "geoip-enricher"
}
}
spec {
replicas = 1
selector {
match_labels = {
app = "geoip-enricher"
}
}
template {
metadata {
labels = {
app = "geoip-enricher"
}
}
spec {
container {
name = "geoip-enricher"
image = "python:3.11-slim"
command = ["/bin/bash"]
args = [
"-c",
"cd /app && pip install -r requirements.txt && python enricher.py"
]
port {
container_port = 8080
name = "http"
}
env {
name = "LOKI_URL"
value = "http://loki:3100"
}
env {
name = "PROMETHEUS_PUSHGATEWAY"
value = "prometheus-pushgateway.prometheus.svc.cluster.local:9091"
}
env {
name = "PYTHONUNBUFFERED"
value = "1"
}
volume_mount {
name = "app-code"
mount_path = "/app"
}
resources {
requests = {
memory = "128Mi"
cpu = "100m"
}
limits = {
memory = "256Mi"
cpu = "200m"
}
}
liveness_probe {
exec {
command = ["python", "-c", "print('healthy')"]
}
initial_delay_seconds = 30
period_seconds = 60
}
}
volume {
name = "app-code"
config_map {
name = kubernetes_config_map.geoip_enricher_code.metadata[0].name
}
}
restart_policy = "Always"
}
}
}
depends_on = [
helm_release.loki,
helm_release.prometheus_pushgateway
]
}
# GeoIP Enricher Service
resource "kubernetes_service" "geoip_enricher" {
metadata {
name = "geoip-enricher"
namespace = kubernetes_namespace.logging.metadata[0].name
labels = {
app = "geoip-enricher"
}
}
spec {
selector = {
app = "geoip-enricher"
}
port {
port = 8080
target_port = 8080
protocol = "TCP"
name = "http"
}
type = "ClusterIP"
}
}
# Grafana Dashboard ConfigMap
resource "kubernetes_config_map" "grafana_dashboard_geoip" {
metadata {
name = "grafana-dashboard-geoip"
namespace = "grafana"
labels = {
grafana_dashboard = "1"
}
}
data = {
"nginx-geo-analytics.json" = file("${path.module}/../grafana-dashboards/nginx-geo-analytics.json")
}
depends_on = [
kubernetes_namespace.grafana
]
}