resource "kubernetes_config_map" "grafana_datasources" { metadata { name = "grafana-datasources" namespace = kubernetes_namespace.grafana.metadata[0].name } data = { "default.yml" = replace(local.grafana_datasource_config, "__PROMETHEUS_URL__", var.prometheus_url) } } resource "kubernetes_config_map" "grafana_dashboard_provider" { metadata { name = "grafana-dashboard-provider" namespace = kubernetes_namespace.grafana.metadata[0].name } data = { "dashboard-provider.yml" = local.grafana_dashboard_provider } } resource "kubernetes_config_map" "grafana_dashboards" { metadata { name = "grafana-dashboards" 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 } } resource "kubernetes_deployment" "grafana" { metadata { name = "grafana" namespace = kubernetes_namespace.grafana.metadata[0].name labels = { app = "grafana" } } spec { selector { match_labels = { app = "grafana" } } template { metadata { labels = { app = "grafana" } } spec { container { name = "grafana" image = "grafana/grafana:${local.app_version}" image_pull_policy = "IfNotPresent" security_context { run_as_user = 1000 run_as_non_root = true privileged = false allow_privilege_escalation = false } port { name = "http-grafana" container_port = 3000 protocol = "TCP" } readiness_probe { http_get { path = "/robots.txt" port = 3000 scheme = "HTTP" } failure_threshold = 3 initial_delay_seconds = 10 period_seconds = 30 success_threshold = 1 timeout_seconds = 2 } liveness_probe { tcp_socket { port = 3000 } failure_threshold = 3 initial_delay_seconds = 30 period_seconds = 10 success_threshold = 1 timeout_seconds = 1 } resources { requests = { cpu = "250m" memory = "750Mi" } } volume_mount { name = "grafana-pv" mount_path = "/var/lib/grafana" } volume_mount { name = "grafana-datasources" mount_path = "/etc/grafana/provisioning/datasources" read_only = true } volume_mount { name = "grafana-dashboard-provider" mount_path = "/etc/grafana/provisioning/dashboards" read_only = true } volume_mount { name = "grafana-dashboards" mount_path = "/var/lib/grafana/dashboards" read_only = true } } volume { name = "grafana-pv" host_path { path = local.monitoring_folder } } volume { name = "grafana-datasources" config_map { name = kubernetes_config_map.grafana_datasources.metadata[0].name } } volume { name = "grafana-dashboard-provider" config_map { 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 } } } } } } resource "kubernetes_service" "grafana" { metadata { name = "grafana" namespace = kubernetes_namespace.grafana.metadata[0].name } spec { selector = { app = "grafana" } port { port = 3000 protocol = "TCP" target_port = "http-grafana" } session_affinity = "None" type = "ClusterIP" } } resource "kubernetes_ingress_v1" "grafana" { metadata { name = "ingress" namespace = kubernetes_namespace.grafana.metadata[0].name annotations = { "kubernetes.io/ingress.class" = "public" "cert-manager.io/cluster-issuer" = "letsencrypt-prod" "kubernetes.io/tls-acme" = "true" "nginx.ingress.kubernetes.io/ssl-redirect" = "true" } } spec { tls { hosts = [var.fqdn] secret_name = "grafana-tls" } rule { host = var.fqdn http { path { backend { service { name = kubernetes_service.grafana.metadata[0].name port { number = 3000 } } } } } } } }