{"id":6440,"date":"2025-09-18T15:06:49","date_gmt":"2025-09-18T13:06:49","guid":{"rendered":"https:\/\/onlu.ch\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/"},"modified":"2025-12-04T17:24:52","modified_gmt":"2025-12-04T16:24:52","slug":"scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd","status":"publish","type":"post","link":"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/","title":{"rendered":"Scaling OpenShift Monitoring with TypeScript, CDK8s, and ArgoCD"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"6440\" class=\"elementor elementor-6440 elementor-6417\" data-elementor-settings=\"{&quot;element_pack_global_tooltip_width&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;element_pack_global_tooltip_width_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;element_pack_global_tooltip_width_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;element_pack_global_tooltip_padding&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;top&quot;:&quot;&quot;,&quot;right&quot;:&quot;&quot;,&quot;bottom&quot;:&quot;&quot;,&quot;left&quot;:&quot;&quot;,&quot;isLinked&quot;:true},&quot;element_pack_global_tooltip_padding_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;top&quot;:&quot;&quot;,&quot;right&quot;:&quot;&quot;,&quot;bottom&quot;:&quot;&quot;,&quot;left&quot;:&quot;&quot;,&quot;isLinked&quot;:true},&quot;element_pack_global_tooltip_padding_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;top&quot;:&quot;&quot;,&quot;right&quot;:&quot;&quot;,&quot;bottom&quot;:&quot;&quot;,&quot;left&quot;:&quot;&quot;,&quot;isLinked&quot;:true},&quot;element_pack_global_tooltip_border_radius&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;top&quot;:&quot;&quot;,&quot;right&quot;:&quot;&quot;,&quot;bottom&quot;:&quot;&quot;,&quot;left&quot;:&quot;&quot;,&quot;isLinked&quot;:true},&quot;element_pack_global_tooltip_border_radius_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;top&quot;:&quot;&quot;,&quot;right&quot;:&quot;&quot;,&quot;bottom&quot;:&quot;&quot;,&quot;left&quot;:&quot;&quot;,&quot;isLinked&quot;:true},&quot;element_pack_global_tooltip_border_radius_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;top&quot;:&quot;&quot;,&quot;right&quot;:&quot;&quot;,&quot;bottom&quot;:&quot;&quot;,&quot;left&quot;:&quot;&quot;,&quot;isLinked&quot;:true}}\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-6a7ab5b5 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"6a7ab5b5\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-29d27782\" data-id=\"29d27782\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-5bbdcdd2 elementor-widget elementor-widget-text-editor\" data-id=\"5bbdcdd2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\n<p data-start=\"114\" data-end=\"359\">Monitoring in Kubernetes and OpenShift is generally recognized as critical. In practice, however, it is often fragmented, inconsistent and difficult to develop further. The bigger and older your platform gets, the worse the problem becomes.  <\/p>\n<p data-start=\"361\" data-end=\"461\">In my case, I was working with an OpenShift landscape that had grown over several years:<\/p>\n<ul data-start=\"462\" data-end=\"645\">\n<li data-start=\"462\" data-end=\"513\">\n<p data-start=\"464\" data-end=\"513\">Multiple test, staging and production clusters<\/p>\n<\/li>\n<li data-start=\"514\" data-end=\"562\">\n<p data-start=\"516\" data-end=\"562\">Numerous teams and services, old and new<\/p>\n<\/li>\n<li data-start=\"563\" data-end=\"645\">\n<p data-start=\"565\" data-end=\"645\">A patchwork of monitoring approaches across different environments<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"647\" data-end=\"677\">The consequences were clear:<\/p>\n<ul data-start=\"678\" data-end=\"888\">\n<li data-start=\"678\" data-end=\"730\">\n<p data-start=\"680\" data-end=\"730\">Some services were not monitored at all<\/p>\n<\/li>\n<li data-start=\"731\" data-end=\"802\">\n<p data-start=\"733\" data-end=\"802\">Others had alarms in one environment but not in another<\/p>\n<\/li>\n<li data-start=\"803\" data-end=\"888\">\n<p data-start=\"805\" data-end=\"888\">No one could say for sure whether the monitoring was really &#8220;complete&#8221;<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"890\" data-end=\"963\">This situation is not sustainable for a platform on a large scale.<\/p>\n<hr data-start=\"965\" data-end=\"968\">\n<h2 data-start=\"970\" data-end=\"1029\">The challenge of grown OpenShift landscapes<\/h2>\n<p data-start=\"1030\" data-end=\"1299\">If you&#8217;ve been running OpenShift for a few years, this story will sound familiar. You start with a single development cluster. Later, you add production clusters. Eventually, you&#8217;re running half a dozen clusters, each with its own peculiarities.   <\/p>\n<p data-start=\"1301\" data-end=\"1341\">Monitoring develops piece by piece:<\/p>\n<ul data-start=\"1342\" data-end=\"1600\">\n<li data-start=\"1342\" data-end=\"1431\">\n<p data-start=\"1344\" data-end=\"1431\">One team sets up Prometheus here, another adds a Grafana dashboard there<\/p>\n<\/li>\n<li data-start=\"1432\" data-end=\"1502\">\n<p data-start=\"1434\" data-end=\"1502\">Rules and alarms are defined manually, often as YAML manifests<\/p>\n<\/li>\n<li data-start=\"1503\" data-end=\"1600\">\n<p data-start=\"1505\" data-end=\"1600\">Configurations drift apart, gaps in coverage arise, fragile systems emerge<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"1602\" data-end=\"1760\">The result is a patchwork of monitoring rules that nobody trusts completely. This is exactly where the &#8220;monitoring as code&#8221; approach changes the game. <\/p>\n<h2 data-start=\"1767\" data-end=\"1807\">The idea: monitoring as a library<\/h2>\n<p data-start=\"1808\" data-end=\"1962\">Instead of maintaining monitoring manifests by hand, I built a TypeScript library based on CDK8s (Cloud Development Kit for Kubernetes).<\/p>\n<p data-start=\"1964\" data-end=\"2308\">This library integrates directly with the Prometheus Operator in OpenShift\/Kubernetes and provides a high-level abstraction for monitoring. Developers do not need to learn PromQL or write PrometheusRule manifests. Instead, they simply declare which services should be monitored and the library takes care of the rest.  <\/p>\n<p data-start=\"2310\" data-end=\"2331\">This is how it works:<\/p>\n<ol data-start=\"2332\" data-end=\"2714\">\n<li data-start=\"2332\" data-end=\"2428\">\n<p data-start=\"2335\" data-end=\"2428\">A consumer project imports the library and declares its monitoring requirements.<\/p>\n<\/li>\n<li data-start=\"2429\" data-end=\"2564\">\n<p data-start=\"2432\" data-end=\"2564\">The CI\/CD pipeline executes <code data-start=\"2457\" data-end=\"2470\">cdk8s synth<\/code>, which generates manifests such as PrometheusRules, ServiceMonitors and PodMonitors.<\/p>\n<\/li>\n<li data-start=\"2565\" data-end=\"2624\">\n<p data-start=\"2568\" data-end=\"2624\">The pipeline commits these manifests back to Git.<\/p>\n<\/li>\n<li data-start=\"2625\" data-end=\"2714\">\n<p data-start=\"2628\" data-end=\"2714\">ArgoCD recognizes the changes and imports them into the appropriate OpenShift cluster.<\/p>\n<\/li>\n<\/ol>\n<p data-start=\"2716\" data-end=\"2805\">Monitoring becomes pure code: versioned, reviewable, automated and repeatable.<\/p>\n<h2 data-start=\"2812\" data-end=\"2864\">How it works: From commit to cluster<\/h2>\n\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"306\" class=\"wp-image-6420\" src=\"https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-18-at-12.14.15-1024x306.png\" alt=\"\" srcset=\"https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-18-at-12.14.15-1024x306.png 1024w, https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-18-at-12.14.15-300x90.png 300w, https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-18-at-12.14.15-768x230.png 768w, https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-18-at-12.14.15-1536x460.png 1536w, https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-18-at-12.14.15-2048x613.png 2048w, https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-18-at-12.14.15-650x195.png 650w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n<h3 data-start=\"2866\" data-end=\"2891\">Developer workflow<\/h3>\n<p data-start=\"2892\" data-end=\"2951\">Onboarding into monitoring is easy for developers:<\/p>\n<ol data-start=\"2952\" data-end=\"3319\">\n<li data-start=\"2952\" data-end=\"3229\">\n<p data-start=\"2955\" data-end=\"2982\"><strong data-start=\"2955\" data-end=\"2980\">Commit your intention<\/strong><\/p>\n<ul data-start=\"2986\" data-end=\"3229\">\n<li data-start=\"2986\" data-end=\"3040\">\n<p data-start=\"2988\" data-end=\"3040\">Declare which service is to be monitored.<\/p>\n<\/li>\n<li data-start=\"3044\" data-end=\"3089\">\n<p data-start=\"3046\" data-end=\"3089\">Specify which stage: INT, SYT, PROD etc.<\/p>\n<\/li>\n<li data-start=\"3093\" data-end=\"3156\">\n<p data-start=\"3095\" data-end=\"3156\">Configure alert channels: e.g. your team&#8217;s Slack channels.<\/p>\n<\/li>\n<li data-start=\"3160\" data-end=\"3229\">\n<p data-start=\"3162\" data-end=\"3229\">Add all required metadata: cluster name, environment, etc.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li data-start=\"3230\" data-end=\"3319\">\n<p data-start=\"3233\" data-end=\"3253\"><strong data-start=\"3233\" data-end=\"3251\">Push to GitLab<\/strong><\/p>\n<ul data-start=\"3257\" data-end=\"3319\">\n<li data-start=\"3257\" data-end=\"3319\">\n<p data-start=\"3259\" data-end=\"3319\">As soon as you push your changes, the pipeline takes over.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p data-start=\"3321\" data-end=\"3416\">That&#8217;s it! Developers only commit TypeScript configuration along with their service code. <\/p>\n<h3 data-start=\"3418\" data-end=\"3443\">Behind the scenes<\/h3>\n<ul data-start=\"3444\" data-end=\"3947\">\n<li data-start=\"3444\" data-end=\"3537\">\n<p data-start=\"3446\" data-end=\"3537\"><strong data-start=\"3446\" data-end=\"3469\">Pipeline execution<\/strong> &#8211; the CI\/CD pipeline calls the TypeScript + CDK8s library.<\/p>\n<\/li>\n<li data-start=\"3538\" data-end=\"3660\">\n<p data-start=\"3540\" data-end=\"3660\"><strong data-start=\"3540\" data-end=\"3560\">YAML generation<\/strong> &#8211; manifests (PrometheusRules, PodMonitors, Alertmanager-Routes etc.) are created automatically.<\/p>\n<\/li>\n<li data-start=\"3661\" data-end=\"3733\">\n<p data-start=\"3663\" data-end=\"3733\"><strong data-start=\"3663\" data-end=\"3682\">GitOps handover<\/strong> &#8211; the manifests are committed back to Git.<\/p>\n<\/li>\n<li data-start=\"3734\" data-end=\"3830\">\n<p data-start=\"3736\" data-end=\"3830\"><strong data-start=\"3736\" data-end=\"3757\">ArgoCD Deployment<\/strong> &#8211; ArgoCD imports the configuration into the appropriate OpenShift stage.<\/p>\n<\/li>\n<li data-start=\"3831\" data-end=\"3947\">\n<p data-start=\"3833\" data-end=\"3947\"><strong data-start=\"3833\" data-end=\"3855\">Active monitoring<\/strong> &#8211; Prometheus and Alertmanager immediately start scraping and evaluating rules.<\/p>\n<\/li>\n<\/ul>\n<h2 data-start=\"3954\" data-end=\"3980\">Features at a glance<\/h2>\n<p data-start=\"3982\" data-end=\"4038\"><strong data-start=\"3985\" data-end=\"4036\">Standard rules (for each declared service)<\/strong><\/p>\n<ul data-start=\"4039\" data-end=\"4389\">\n<li data-start=\"4039\" data-end=\"4123\">\n<p data-start=\"4041\" data-end=\"4123\">Unwanted Pod Existence &#8211; discovers new services that are not yet monitored<\/p>\n<\/li>\n<li data-start=\"4124\" data-end=\"4177\">\n<p data-start=\"4126\" data-end=\"4177\">Missing Metrics &#8211; marked services without metrics<\/p>\n<\/li>\n<li data-start=\"4178\" data-end=\"4241\">\n<p data-start=\"4180\" data-end=\"4241\">Pod Pending &#8211; alerts if pods remain pending for too long<\/p>\n<\/li>\n<li data-start=\"4242\" data-end=\"4304\">\n<p data-start=\"4244\" data-end=\"4304\">Pod crashing &#8211; detects crash loops or frequent restarts<\/p>\n<\/li>\n<li data-start=\"4305\" data-end=\"4389\">\n<p data-start=\"4307\" data-end=\"4389\">Pod Availability &#8211; ensures that replicas meet the availability targets<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"4391\" data-end=\"4453\"><strong data-start=\"4394\" data-end=\"4451\">Additional rules (added dynamically if required)<\/strong><\/p>\n<ul data-start=\"4454\" data-end=\"4735\">\n<li data-start=\"4454\" data-end=\"4513\">\n<p data-start=\"4456\" data-end=\"4513\">PVC Thresholds &#8211; monitors persistent volume utilization<\/p>\n<\/li>\n<li data-start=\"4514\" data-end=\"4576\">\n<p data-start=\"4516\" data-end=\"4576\">Kafka Rules &#8211; monitors consumer lag and broker health<\/p>\n<\/li>\n<li data-start=\"4577\" data-end=\"4643\">\n<p data-start=\"4579\" data-end=\"4643\">HTTP Rules &#8211; checks REST endpoints for availability and latency<\/p>\n<\/li>\n<li data-start=\"4644\" data-end=\"4735\">\n<p data-start=\"4646\" data-end=\"4735\">Custom PromQL &#8211; wraps user-defined queries in standardized PrometheusRules<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"4737\" data-end=\"4784\"><strong data-start=\"4740\" data-end=\"4782\">Alerting &amp; notification integrations<\/strong><\/p>\n<ul data-start=\"4785\" data-end=\"4934\">\n<li data-start=\"4785\" data-end=\"4846\">\n<p data-start=\"4787\" data-end=\"4846\">Slack integration &#8211; standard and team-specific channels<\/p>\n<\/li>\n<li data-start=\"4847\" data-end=\"4934\">\n<p data-start=\"4849\" data-end=\"4934\">ITIL\/Webhook integration &#8211; forwards alarms to ticketing or incident systems<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"4936\" data-end=\"4968\"><strong data-start=\"4939\" data-end=\"4966\">Ecosystem integrations<\/strong><\/p>\n<ul data-start=\"4969\" data-end=\"5395\">\n<li data-start=\"4969\" data-end=\"5142\">\n<p data-start=\"4971\" data-end=\"5001\"><strong data-start=\"4971\" data-end=\"4999\">ConfigMaps with metadata<\/strong><\/p>\n<ul data-start=\"5004\" data-end=\"5142\">\n<li data-start=\"5004\" data-end=\"5067\">\n<p data-start=\"5006\" data-end=\"5067\">Automatically generated, e.g. service names, environments, etc.<\/p>\n<\/li>\n<li data-start=\"5070\" data-end=\"5142\">\n<p data-start=\"5072\" data-end=\"5142\">Third-party tools such as Grafana can use these variables for dashboards.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li data-start=\"5143\" data-end=\"5395\">\n<p data-start=\"5145\" data-end=\"5194\"><strong data-start=\"5145\" data-end=\"5192\">RBAC resources for centralized metrics<\/strong><\/p>\n<ul data-start=\"5197\" data-end=\"5395\">\n<li data-start=\"5197\" data-end=\"5273\">\n<p data-start=\"5199\" data-end=\"5273\">Creates RBAC policies so that service metrics are collected securely.<\/p>\n<\/li>\n<li data-start=\"5276\" data-end=\"5395\">\n<p data-start=\"5278\" data-end=\"5395\">All metrics flow into a central Thanos pool &#8211; global queries and standardized dashboards become possible.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p data-start=\"5397\" data-end=\"5438\"><strong data-start=\"5400\" data-end=\"5436\">Governance &amp; traceability<\/strong><\/p>\n<ul data-start=\"5439\" data-end=\"5602\">\n<li data-start=\"5439\" data-end=\"5602\">\n<p data-start=\"5441\" data-end=\"5602\">Version annotations \u2192 Each resource is annotated with the library version that created it &#8211; outdated or depreciated rules are easily recognizable.<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"5604\" data-end=\"5636\"><strong data-start=\"5607\" data-end=\"5634\">GitOps-capable workflow<\/strong><\/p>\n<ul data-start=\"5637\" data-end=\"5856\">\n<li data-start=\"5637\" data-end=\"5684\">\n<p data-start=\"5639\" data-end=\"5684\">Automated YAML generation via CDK8s.<\/p>\n<\/li>\n<li data-start=\"5685\" data-end=\"5753\">\n<p data-start=\"5687\" data-end=\"5753\">GitOps pipeline integration: Manifests are committed to Git.<\/p>\n<\/li>\n<li data-start=\"5754\" data-end=\"5856\">\n<p data-start=\"5756\" data-end=\"5856\">ArgoCD Deployment ensures that monitoring resources are always synchronized and self-healing.<\/p>\n<\/li>\n<\/ul>\n<h2 data-start=\"5863\" data-end=\"5880\">End2End image<\/h2>\n\n<p>The following image describes the end-to-end process &#8211; from the consumer&#8217;s code to the deployed alarm rule.<\/p>\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"550\" class=\"wp-image-6500\" src=\"https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-24-at-14.33.56-1024x550.png\" alt=\"\" srcset=\"https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-24-at-14.33.56-1024x550.png 1024w, https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-24-at-14.33.56-300x161.png 300w, https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-24-at-14.33.56-768x413.png 768w, https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-24-at-14.33.56-1536x825.png 1536w, https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-24-at-14.33.56-2048x1101.png 2048w, https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-24-at-14.33.56-650x349.png 650w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"581\" class=\"wp-image-6503\" src=\"https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-26-at-09.06.14-1024x581.png\" alt=\"\" srcset=\"https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-26-at-09.06.14-1024x581.png 1024w, https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-26-at-09.06.14-300x170.png 300w, https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-26-at-09.06.14-768x436.png 768w, https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-26-at-09.06.14-1536x872.png 1536w, https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-26-at-09.06.14-2048x1162.png 2048w, https:\/\/onlu.ch\/wp-content\/uploads\/2025\/09\/Screenshot-2025-09-26-at-09.06.14-650x369.png 650w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n<h2 data-start=\"5996\" data-end=\"6022\">Why this is important<\/h2>\n<p data-start=\"6023\" data-end=\"6105\">Monitoring should not be a fragile patchwork of YAML files. It should be: <\/p>\n<ul data-start=\"6106\" data-end=\"6424\">\n<li data-start=\"6106\" data-end=\"6176\">\n<p data-start=\"6108\" data-end=\"6176\"><strong data-start=\"6108\" data-end=\"6122\">Declarative<\/strong> &#8211; defined as an intention, not manually configured<\/p>\n<\/li>\n<li data-start=\"6177\" data-end=\"6239\">\n<p data-start=\"6179\" data-end=\"6239\"><strong data-start=\"6179\" data-end=\"6196\">Automated<\/strong> &#8211; generated and deployed by pipelines<\/p>\n<\/li>\n<li data-start=\"6240\" data-end=\"6306\">\n<p data-start=\"6242\" data-end=\"6306\"><strong data-start=\"6242\" data-end=\"6256\">Consistent<\/strong> &#8211; applied uniformly across environments<\/p>\n<\/li>\n<li data-start=\"6307\" data-end=\"6357\">\n<p data-start=\"6309\" data-end=\"6357\"><strong data-start=\"6309\" data-end=\"6320\">Testable<\/strong> &#8211; validatable like application code<\/p>\n<\/li>\n<li data-start=\"6358\" data-end=\"6424\">\n<p data-start=\"6360\" data-end=\"6424\"><strong data-start=\"6360\" data-end=\"6379\">Traceable<\/strong> &#8211; versioned and annotated for governance<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"6426\" data-end=\"6614\">By combining TypeScript, CDK8s and ArgoCD, we have created a monitoring system that scales naturally with our OpenShift landscape instead of slowing it down.<\/p>\n<ul data-start=\"6616\" data-end=\"6726\">\n<li data-start=\"6616\" data-end=\"6654\">\n<p data-start=\"6618\" data-end=\"6654\">Defined once in the library<\/p>\n<\/li>\n<li data-start=\"6655\" data-end=\"6688\">\n<p data-start=\"6657\" data-end=\"6688\">Consistently applied everywhere<\/p>\n<\/li>\n<li data-start=\"6689\" data-end=\"6726\">\n<p data-start=\"6691\" data-end=\"6726\">New services integrated effortlessly<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"6728\" data-end=\"6892\">Monitoring is no longer optional or an afterthought. It is built-in, standardized, self-healing &#8211; a <strong data-start=\"6852\" data-end=\"6875\">first-class citizen<\/strong> of the platform. <\/p>\n\n<p> <\/p>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Monitoring in Kubernetes and OpenShift is generally recognized as critical. In practice, however, it is often fragmented, inconsistent and difficult to develop further. The bigger and older your platform gets, [&hellip;]<\/p>\n","protected":false},"author":12,"featured_media":5592,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-6440","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-nicht-kategorisiert"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Scaling OpenShift Monitoring with TypeScript, CDK8s, and ArgoCD - ONLU AG<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Scaling OpenShift Monitoring with TypeScript, CDK8s, and ArgoCD - ONLU AG\" \/>\n<meta property=\"og:description\" content=\"Monitoring in Kubernetes and OpenShift is generally recognized as critical. In practice, however, it is often fragmented, inconsistent and difficult to develop further. The bigger and older your platform gets, [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/\" \/>\n<meta property=\"og:site_name\" content=\"ONLU AG\" \/>\n<meta property=\"article:published_time\" content=\"2025-09-18T13:06:49+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-12-04T16:24:52+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/onlu.ch\/wp-content\/uploads\/2025\/01\/ONLUBannerBlog-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"683\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Christoph Linse\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Christoph Linse\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\\\/\"},\"author\":{\"name\":\"Christoph Linse\",\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/#\\\/schema\\\/person\\\/0e9364e73631edf8539a5f0b9d951caf\"},\"headline\":\"Scaling OpenShift Monitoring with TypeScript, CDK8s, and ArgoCD\",\"datePublished\":\"2025-09-18T13:06:49+00:00\",\"dateModified\":\"2025-12-04T16:24:52+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\\\/\"},\"wordCount\":862,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/onlu.ch\\\/wp-content\\\/uploads\\\/2025\\\/01\\\/ONLUBannerBlog-1.png\",\"articleSection\":[\"Nicht kategorisiert\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/onlu.ch\\\/en\\\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\\\/\",\"url\":\"https:\\\/\\\/onlu.ch\\\/en\\\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\\\/\",\"name\":\"Scaling OpenShift Monitoring with TypeScript, CDK8s, and ArgoCD - ONLU AG\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/onlu.ch\\\/wp-content\\\/uploads\\\/2025\\\/01\\\/ONLUBannerBlog-1.png\",\"datePublished\":\"2025-09-18T13:06:49+00:00\",\"dateModified\":\"2025-12-04T16:24:52+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/onlu.ch\\\/en\\\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\\\/#primaryimage\",\"url\":\"https:\\\/\\\/onlu.ch\\\/wp-content\\\/uploads\\\/2025\\\/01\\\/ONLUBannerBlog-1.png\",\"contentUrl\":\"https:\\\/\\\/onlu.ch\\\/wp-content\\\/uploads\\\/2025\\\/01\\\/ONLUBannerBlog-1.png\",\"width\":1024,\"height\":683},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\\\/\\\/onlu.ch\\\/en\\\/home-page\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Scaling OpenShift Monitoring with TypeScript, CDK8s, and ArgoCD\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/#website\",\"url\":\"https:\\\/\\\/onlu.ch\\\/en\\\/\",\"name\":\"ONLU AG\",\"description\":\"Massgeschneiderte Software \u2013 Ihr hoch-qualifiziertes IT Team\",\"publisher\":{\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/onlu.ch\\\/en\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/#organization\",\"name\":\"ONLU AG\",\"alternateName\":\"ONLU.CH\",\"url\":\"https:\\\/\\\/onlu.ch\\\/en\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/onlu.ch\\\/wp-content\\\/uploads\\\/2023\\\/06\\\/onlu-logo-red-arrow.png\",\"contentUrl\":\"https:\\\/\\\/onlu.ch\\\/wp-content\\\/uploads\\\/2023\\\/06\\\/onlu-logo-red-arrow.png\",\"width\":800,\"height\":221,\"caption\":\"ONLU AG\"},\"image\":{\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/ch.linkedin.com\\\/company\\\/onlu\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/onlu.ch\\\/en\\\/#\\\/schema\\\/person\\\/0e9364e73631edf8539a5f0b9d951caf\",\"name\":\"Christoph Linse\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3a295372eae36b7fa132ff908936fec734764799ddec57d186881d0f2a164372?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3a295372eae36b7fa132ff908936fec734764799ddec57d186881d0f2a164372?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3a295372eae36b7fa132ff908936fec734764799ddec57d186881d0f2a164372?s=96&d=mm&r=g\",\"caption\":\"Christoph Linse\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Scaling OpenShift Monitoring with TypeScript, CDK8s, and ArgoCD - ONLU AG","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/","og_locale":"en_US","og_type":"article","og_title":"Scaling OpenShift Monitoring with TypeScript, CDK8s, and ArgoCD - ONLU AG","og_description":"Monitoring in Kubernetes and OpenShift is generally recognized as critical. In practice, however, it is often fragmented, inconsistent and difficult to develop further. The bigger and older your platform gets, [&hellip;]","og_url":"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/","og_site_name":"ONLU AG","article_published_time":"2025-09-18T13:06:49+00:00","article_modified_time":"2025-12-04T16:24:52+00:00","og_image":[{"width":1024,"height":683,"url":"https:\/\/onlu.ch\/wp-content\/uploads\/2025\/01\/ONLUBannerBlog-1.png","type":"image\/png"}],"author":"Christoph Linse","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Christoph Linse","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/#article","isPartOf":{"@id":"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/"},"author":{"name":"Christoph Linse","@id":"https:\/\/onlu.ch\/en\/#\/schema\/person\/0e9364e73631edf8539a5f0b9d951caf"},"headline":"Scaling OpenShift Monitoring with TypeScript, CDK8s, and ArgoCD","datePublished":"2025-09-18T13:06:49+00:00","dateModified":"2025-12-04T16:24:52+00:00","mainEntityOfPage":{"@id":"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/"},"wordCount":862,"commentCount":0,"publisher":{"@id":"https:\/\/onlu.ch\/en\/#organization"},"image":{"@id":"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/#primaryimage"},"thumbnailUrl":"https:\/\/onlu.ch\/wp-content\/uploads\/2025\/01\/ONLUBannerBlog-1.png","articleSection":["Nicht kategorisiert"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/","url":"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/","name":"Scaling OpenShift Monitoring with TypeScript, CDK8s, and ArgoCD - ONLU AG","isPartOf":{"@id":"https:\/\/onlu.ch\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/#primaryimage"},"image":{"@id":"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/#primaryimage"},"thumbnailUrl":"https:\/\/onlu.ch\/wp-content\/uploads\/2025\/01\/ONLUBannerBlog-1.png","datePublished":"2025-09-18T13:06:49+00:00","dateModified":"2025-12-04T16:24:52+00:00","breadcrumb":{"@id":"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/#primaryimage","url":"https:\/\/onlu.ch\/wp-content\/uploads\/2025\/01\/ONLUBannerBlog-1.png","contentUrl":"https:\/\/onlu.ch\/wp-content\/uploads\/2025\/01\/ONLUBannerBlog-1.png","width":1024,"height":683},{"@type":"BreadcrumbList","@id":"https:\/\/onlu.ch\/en\/scaling-openshift-monitoring-with-typescriptcdk8s-and-argocd\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/onlu.ch\/en\/home-page\/"},{"@type":"ListItem","position":2,"name":"Scaling OpenShift Monitoring with TypeScript, CDK8s, and ArgoCD"}]},{"@type":"WebSite","@id":"https:\/\/onlu.ch\/en\/#website","url":"https:\/\/onlu.ch\/en\/","name":"ONLU AG","description":"Massgeschneiderte Software \u2013 Ihr hoch-qualifiziertes IT Team","publisher":{"@id":"https:\/\/onlu.ch\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/onlu.ch\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/onlu.ch\/en\/#organization","name":"ONLU AG","alternateName":"ONLU.CH","url":"https:\/\/onlu.ch\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/onlu.ch\/en\/#\/schema\/logo\/image\/","url":"https:\/\/onlu.ch\/wp-content\/uploads\/2023\/06\/onlu-logo-red-arrow.png","contentUrl":"https:\/\/onlu.ch\/wp-content\/uploads\/2023\/06\/onlu-logo-red-arrow.png","width":800,"height":221,"caption":"ONLU AG"},"image":{"@id":"https:\/\/onlu.ch\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/ch.linkedin.com\/company\/onlu"]},{"@type":"Person","@id":"https:\/\/onlu.ch\/en\/#\/schema\/person\/0e9364e73631edf8539a5f0b9d951caf","name":"Christoph Linse","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/3a295372eae36b7fa132ff908936fec734764799ddec57d186881d0f2a164372?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/3a295372eae36b7fa132ff908936fec734764799ddec57d186881d0f2a164372?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3a295372eae36b7fa132ff908936fec734764799ddec57d186881d0f2a164372?s=96&d=mm&r=g","caption":"Christoph Linse"}}]}},"_links":{"self":[{"href":"https:\/\/onlu.ch\/en\/wp-json\/wp\/v2\/posts\/6440","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/onlu.ch\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/onlu.ch\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/onlu.ch\/en\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/onlu.ch\/en\/wp-json\/wp\/v2\/comments?post=6440"}],"version-history":[{"count":7,"href":"https:\/\/onlu.ch\/en\/wp-json\/wp\/v2\/posts\/6440\/revisions"}],"predecessor-version":[{"id":6517,"href":"https:\/\/onlu.ch\/en\/wp-json\/wp\/v2\/posts\/6440\/revisions\/6517"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/onlu.ch\/en\/wp-json\/wp\/v2\/media\/5592"}],"wp:attachment":[{"href":"https:\/\/onlu.ch\/en\/wp-json\/wp\/v2\/media?parent=6440"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/onlu.ch\/en\/wp-json\/wp\/v2\/categories?post=6440"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/onlu.ch\/en\/wp-json\/wp\/v2\/tags?post=6440"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}