From 282fc205dc40923cdb4d3b2a941a20081fd305d0 Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Wed, 11 Feb 2026 10:30:55 +0530 Subject: [PATCH 1/9] feat(helm): deploying the netobserv operator chart --- modules/helm/netobserv.tf | 12 ++++++++++++ modules/helm/variables.tf | 14 ++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 modules/helm/netobserv.tf diff --git a/modules/helm/netobserv.tf b/modules/helm/netobserv.tf new file mode 100644 index 0000000..63c8639 --- /dev/null +++ b/modules/helm/netobserv.tf @@ -0,0 +1,12 @@ +# Netobserv Configuration +resource "helm_release" "netobserv" { + name = var.netobserv_configuration.name + namespace = var.netobserv_configuration.namespace + repository = var.netobserv_configuration.repository + chart = var.netobserv_configuration.chart + version = var.netobserv_configuration.version + create_namespace = var.netobserv_configuration.create_namespace + + depends_on = [ helm_release.calico ] + timeout = 1800 +} diff --git a/modules/helm/variables.tf b/modules/helm/variables.tf index 91ed347..ba427d4 100644 --- a/modules/helm/variables.tf +++ b/modules/helm/variables.tf @@ -100,6 +100,20 @@ variable "calico_configuration" { } } +# --------------- CALICO OPERATOR VARIABLES --------------- # +variable "netobserv_configuration" { + description = "Dictionary filled with Netobserv Operator Configuration Details" + type = map(string) + default = { + "name" = "netobserv" + "namespace" = "netobserv" + "repository" = "https://netobserv.io/static/helm" + "chart" = "netobserv-operator" + "version" = "1.11.0" + "create_namespace" = true + } +} + # --------------- NODE SELECTOR VARIABLE --------------- # variable "server_node_selector" { description = "Node Selector Label Value to be used for deploying required foundation components" From 5d927a571a30f3e4819f0f57249b6f934c4c5c0a Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Wed, 11 Feb 2026 10:31:38 +0530 Subject: [PATCH 2/9] feat(observability): netobserv deployment + otel collector config adjustment --- .../observability/network_observability.tf | 98 +++++++++++++++++++ modules/observability/otel-collector.tf | 26 ++++- 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 modules/observability/network_observability.tf diff --git a/modules/observability/network_observability.tf b/modules/observability/network_observability.tf new file mode 100644 index 0000000..169962e --- /dev/null +++ b/modules/observability/network_observability.tf @@ -0,0 +1,98 @@ +resource "kubernetes_manifest" "network_observability" { + manifest = { + apiVersion = "flows.netobserv.io/v1beta2" + kind = "FlowCollector" + metadata = { + # The operator expects this specific name + name = "cluster" + } + spec = { + namespace = kubernetes_namespace.namespace.metadata[0].name + + # "Direct" mode sends logs straight to OTel (bypassing Kafka/IPFIX) + deploymentModel = "Direct" + + agent = { + type = "eBPF" + ebpf = { + # PRIVILEGED: Required for "PacketDrop" to read kernel drop reasons + privileged = true + + # FEATURES: Enable drop detection + features = ["PacketDrop"] + + # SAMPLING: 25 means 1 in 25 packets + sampling = 25 + cacheActiveTimeout = "15s" + cacheMaxFlows = 100000 + excludeInterfaces = ["lo"] # Ignore loopback traffic + + # Resource Constraints + resources = { + requests = { + cpu = "50m" + memory = "100Mi" + } + limits = { + cpu = "500m" # Hard cap to prevent eBPF compiler spikes + memory = "512Mi" # Hard cap to prevent leaks + } + } + } + } + + # Disable default stack for the netobserv instance + loki = { + enable = false + } + prometheus = { + querier = { + enable = false + } + } + consolePlugin = { + enable = false + } + + # PROCESSOR: Enrichment settings + processor = { + logTypes = "Flows" + metrics = { + # Disable agent-side metrics generation to save CPU + # We will derive metrics from logs in Victoria if needed + disableAlerts = ["NetObservLokiError", "NetObservNoFlows"] + ignoreTags = ["nodes", "workloads"] + } + } + + # EXPORT: Pushing to the OTel Collector + exporters = [ + { + type = "OpenTelemetry" + openTelemetry = { + # 1. POINT THIS TO YOUR OTEL COLLECTOR SERVICE + # Format: ..svc.cluster.local + targetHost = "otel-collector.${kubernetes_namespace.namespace.metadata[0].name}.svc.cluster.local" + targetPort = 4317 + protocol = "grpc" + + logs = { + enable = true + pushTimeInterval = "20s" + expiryTime = "2m" + } + + # Disable direct metric export (optional) + metrics = { + enable = false + } + tls = { + enable = false + insecureSkipVerify = true + } + } + } + ] + } + } +} diff --git a/modules/observability/otel-collector.tf b/modules/observability/otel-collector.tf index a00a6a1..d88cdef 100644 --- a/modules/observability/otel-collector.tf +++ b/modules/observability/otel-collector.tf @@ -8,6 +8,8 @@ resource "helm_release" "otel_collector" { values = [ yamlencode({ + fullnameOverride = "otel-collector" + mode = "daemonset" # Contrib image supports all required features @@ -53,6 +55,13 @@ resource "helm_release" "otel_collector" { # Custom Configuration for receivers config = { receivers = { + # OTLP Endpoints to send stuff to this collector + otlp = { + protocols = { + grpc = { endpoint = "0.0.0.0:4317" } + http = { endpoint = "0.0.0.0:4318" } + } + } # Scrape annotated pods (prometheus.io/scrape: "true") prometheus = { config = { @@ -111,6 +120,16 @@ resource "helm_release" "otel_collector" { limit_mib = 400 # Hard cap for the process (leaving 112Mi buffer for OS) spike_limit_mib = 100 } + # Tag Netobserv logs appropriately + "resource/netobserv" = { + attributes = [ + { + key = "log.source" + value = "netobserv" + action = "insert" + } + ] + } } # Exporters @@ -143,7 +162,7 @@ resource "helm_release" "otel_collector" { } logs = { # 'filelog' comes from the logsCollection preset - receivers = ["otlp", "filelog"] + receivers = ["filelog"] processors = ["memory_limiter", "k8sattributes", "batch"] exporters = ["otlphttp"] } @@ -155,6 +174,11 @@ resource "helm_release" "otel_collector" { processors = ["memory_limiter", "batch"] exporters = ["debug"] } + "logs/netobserv" = { + receivers = ["otlp"] + processors = ["memory_limiter", "resource/netobserv", "batch"] + exporters = ["otlphttp"] + } } } } From 6a121702ec632ba8a1b0316c2d23097deeb2d392 Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Wed, 11 Feb 2026 10:32:02 +0530 Subject: [PATCH 3/9] feat(infrastructure): feature branch deployment --- infrastructure/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/infrastructure/main.tf b/infrastructure/main.tf index a8fcb8b..7d12630 100644 --- a/infrastructure/main.tf +++ b/infrastructure/main.tf @@ -9,7 +9,7 @@ data "kubernetes_endpoints_v1" "kubernetes_api_endpoint" { # Deploy all required helm charts for deploying the infrastructure module "helm" { - source = "git::https://github.com/necro-cloud/modules//modules/helm?ref=main" + source = "git::https://github.com/necro-cloud/modules//modules/helm?ref=task/76/netobserv-deployment" server_node_selector = "cloud" } @@ -22,7 +22,7 @@ module "cluster-issuer" { # Complete Observability Stack Deployment module "observability" { - source = "git::https://github.com/necro-cloud/modules//modules/observability?ref=main" + source = "git::https://github.com/necro-cloud/modules//modules/observability?ref=task/76/netobserv-deployment" depends_on = [module.cluster-issuer] } From 0c223ed6ba135f7451d283aa82cfbbfc17cd5d21 Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Wed, 11 Feb 2026 10:38:13 +0530 Subject: [PATCH 4/9] fix(helm): netobserv dependency on cert-manager --- modules/helm/netobserv.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/helm/netobserv.tf b/modules/helm/netobserv.tf index 63c8639..2f9081c 100644 --- a/modules/helm/netobserv.tf +++ b/modules/helm/netobserv.tf @@ -7,6 +7,6 @@ resource "helm_release" "netobserv" { version = var.netobserv_configuration.version create_namespace = var.netobserv_configuration.create_namespace - depends_on = [ helm_release.calico ] + depends_on = [ helm_release.calico, helm_release.cert-manager ] timeout = 1800 } From f39f73638ff600dac0c1f5e1e116bc0af29e1059 Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Wed, 11 Feb 2026 10:41:18 +0530 Subject: [PATCH 5/9] fix(observability): netobserv fixes --- modules/observability/network_observability.tf | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/observability/network_observability.tf b/modules/observability/network_observability.tf index 169962e..f12e738 100644 --- a/modules/observability/network_observability.tf +++ b/modules/observability/network_observability.tf @@ -61,7 +61,6 @@ resource "kubernetes_manifest" "network_observability" { # Disable agent-side metrics generation to save CPU # We will derive metrics from logs in Victoria if needed disableAlerts = ["NetObservLokiError", "NetObservNoFlows"] - ignoreTags = ["nodes", "workloads"] } } From 9726a1d09bd24711809bfb921744b2a94f261dbb Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Wed, 11 Feb 2026 11:15:08 +0530 Subject: [PATCH 6/9] fix(observability): service configuration for otel collector --- modules/observability/network_observability.tf | 4 +++- modules/observability/otel-collector.tf | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/observability/network_observability.tf b/modules/observability/network_observability.tf index f12e738..60be86b 100644 --- a/modules/observability/network_observability.tf +++ b/modules/observability/network_observability.tf @@ -93,5 +93,7 @@ resource "kubernetes_manifest" "network_observability" { } ] } - } + } + + depends_on = [ helm_release.otel_collector ] } diff --git a/modules/observability/otel-collector.tf b/modules/observability/otel-collector.tf index d88cdef..09a815c 100644 --- a/modules/observability/otel-collector.tf +++ b/modules/observability/otel-collector.tf @@ -12,6 +12,22 @@ resource "helm_release" "otel_collector" { mode = "daemonset" + # Enable service creation for pushing logs and metrics + service = { + enabled = true + } + + // Ports for the service to use + ports = { + otlp = { + enabled = true + containerPort = 4317 + servicePort = 4317 + hostPort = 4317 + protocol = "TCP" + } + } + # Contrib image supports all required features image = { repository = "otel/opentelemetry-collector-contrib" From 5ea0bbb5209b7741c79772e7ab9eb6c8a056b70e Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Wed, 11 Feb 2026 11:25:00 +0530 Subject: [PATCH 7/9] fix(observability): no affinity required for otel collector daemonsets --- modules/observability/otel-collector.tf | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/modules/observability/otel-collector.tf b/modules/observability/otel-collector.tf index 09a815c..3a96f05 100644 --- a/modules/observability/otel-collector.tf +++ b/modules/observability/otel-collector.tf @@ -210,24 +210,6 @@ resource "helm_release" "otel_collector" { memory = "512Mi" } } - - # Placement (Pinned to Worker Nodes) - affinity = { - nodeAffinity = { - requiredDuringSchedulingIgnoredDuringExecution = { - nodeSelectorTerms = [ - { - matchExpressions = [ - { - key = "worker" - operator = "Exists" - } - ] - } - ] - } - } - } }) ] } From 63c1872fee46fcec143469fecc6ceaf05d018605 Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Wed, 11 Feb 2026 11:36:26 +0530 Subject: [PATCH 8/9] docs(helm): README update --- modules/helm/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/helm/README.md b/modules/helm/README.md index 91a912b..c27c3e2 100644 --- a/modules/helm/README.md +++ b/modules/helm/README.md @@ -6,6 +6,7 @@ OpenTofu Module to deploy the following required helm charts: 3. [NGINX Ingress](https://github.com/kubernetes/ingress-nginx) 4. [Kubernetes Reflector](https://github.com/emberstack/kubernetes-reflector) 5. [Calico CNI](https://www.tigera.io/project-calico/) +6. [NetObserv](https://github.com/netobserv) ## Providers @@ -22,6 +23,7 @@ OpenTofu Module to deploy the following required helm charts: | [helm_release.cnpg](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [helm_release.cnpg_barman_plugin](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [helm_release.minio](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | +| [helm_release.netobserv](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [helm_release.nginx](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [helm_release.reflector](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | @@ -35,6 +37,7 @@ OpenTofu Module to deploy the following required helm charts: | [cnpg\_configuration](#input\_cnpg\_configuration) | Dictionary filled with Cloud Native PG Operator Configuration Details | `map(string)` |
{
"chart": "cloudnative-pg",
"create_namespace": true,
"name": "cnpg",
"namespace": "cnpg-system",
"repository": "https://cloudnative-pg.github.io/charts",
"version": "v0.26.0"
}
| no | | [enable\_minio](#input\_enable\_minio) | To enable MinIO Deployment or not | `bool` | `false` | no | | [minio\_operator\_configuration](#input\_minio\_operator\_configuration) | Dictionary filled with MinIO Operator Configuration Details | `map(string)` |
{
"chart": "operator",
"create_namespace": true,
"name": "minio-operator",
"namespace": "minio-operator",
"repository": "https://operator.min.io",
"version": "7.0.0"
}
| no | +| [netobserv\_configuration](#input\_netobserv\_configuration) | Dictionary filled with Netobserv Operator Configuration Details | `map(string)` |
{
"chart": "netobserv-operator",
"create_namespace": true,
"name": "netobserv",
"namespace": "netobserv",
"repository": "https://netobserv.io/static/helm",
"version": "1.11.0"
}
| no | | [nginx\_configuration](#input\_nginx\_configuration) | Dictionary filled with NGINX Controller Configuration Details | `map(string)` |
{
"chart": "ingress-nginx",
"create_namespace": true,
"name": "ingress-nginx",
"namespace": "ingress-nginx",
"repository": "https://kubernetes.github.io/ingress-nginx",
"version": "4.13.3"
}
| no | | [reflector\_configuration](#input\_reflector\_configuration) | Dictionary filled with Kubernetes Reflector Configuration Details | `map(string)` |
{
"chart": "reflector",
"create_namespace": true,
"name": "reflector",
"namespace": "reflector",
"repository": "https://emberstack.github.io/helm-charts",
"version": "v9.1.35"
}
| no | | [server\_node\_selector](#input\_server\_node\_selector) | Node Selector Label Value to be used for deploying required foundation components | `string` | n/a | yes | From 72862e1b435b87071d27d1d6cc6dea11cfe45db9 Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Wed, 11 Feb 2026 11:41:07 +0530 Subject: [PATCH 9/9] [INF] All modules switch to main branch --- infrastructure/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/infrastructure/main.tf b/infrastructure/main.tf index 7d12630..a8fcb8b 100644 --- a/infrastructure/main.tf +++ b/infrastructure/main.tf @@ -9,7 +9,7 @@ data "kubernetes_endpoints_v1" "kubernetes_api_endpoint" { # Deploy all required helm charts for deploying the infrastructure module "helm" { - source = "git::https://github.com/necro-cloud/modules//modules/helm?ref=task/76/netobserv-deployment" + source = "git::https://github.com/necro-cloud/modules//modules/helm?ref=main" server_node_selector = "cloud" } @@ -22,7 +22,7 @@ module "cluster-issuer" { # Complete Observability Stack Deployment module "observability" { - source = "git::https://github.com/necro-cloud/modules//modules/observability?ref=task/76/netobserv-deployment" + source = "git::https://github.com/necro-cloud/modules//modules/observability?ref=main" depends_on = [module.cluster-issuer] }