diff --git a/README.md b/README.md
index b0aab96964dc22e9d10b4e5c7112a0220002dee6..361fa7f9166062a11b10c7914fde106addb03f6d 100644
--- a/README.md
+++ b/README.md
@@ -207,15 +207,15 @@ Here's [example.jsonnet](example.jsonnet):
 [embedmd]:# (example.jsonnet)
 ```jsonnet
 local kp =
-  (import 'kube-prometheus/kube-prometheus.libsonnet') +
+  (import 'kube-prometheus/main.libsonnet') +
   // Uncomment the following imports to enable its patches
-  // (import 'kube-prometheus/kube-prometheus-anti-affinity.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-managed-cluster.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-node-ports.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-thanos-sidecar.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-custom-metrics.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-external-metrics.libsonnet') +
+  // (import 'kube-prometheus/addons/anti-affinity.libsonnet') +
+  // (import 'kube-prometheus/addons/managed-cluster.libsonnet') +
+  // (import 'kube-prometheus/addons/node-ports.libsonnet') +
+  // (import 'kube-prometheus/addons/static-etcd.libsonnet') +
+  // (import 'kube-prometheus/addons/thanos-sidecar.libsonnet') +
+  // (import 'kube-prometheus/addons/custom-metrics.libsonnet') +
+  // (import 'kube-prometheus/addons/external-metrics.libsonnet') +
   {
     values+:: {
       common+: {
@@ -233,14 +233,14 @@ local kp =
 { 'prometheus-operator-serviceMonitor': kp.prometheusOperator.serviceMonitor } +
 { 'prometheus-operator-prometheusRule': kp.prometheusOperator.prometheusRule } +
 { 'kube-prometheus-prometheusRule': kp.kubePrometheus.prometheusRule } +
-{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
-{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) } +
-{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
 { ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
-{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
-{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +
+{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) } +
 { ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
+{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
 { ['kubernetes-' + name]: kp.kubernetesMixin[name] for name in std.objectFields(kp.kubernetesMixin) }
+{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
+{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
+{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) }
 ```
 
 And here's the [build.sh](build.sh) script (which uses `vendor/` to render all manifests in a json structure of `{filename: manifest-content}`):
@@ -413,24 +413,24 @@ kubeadm:
 
 [embedmd]:# (examples/jsonnet-snippets/kubeadm.jsonnet)
 ```jsonnet
-(import 'kube-prometheus/kube-prometheus.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-kubeadm.libsonnet')
+(import 'kube-prometheus/main.libsonnet') +
+(import 'kube-prometheus/platforms/kubeadm.libsonnet')
 ```
 
 bootkube:
 
 [embedmd]:# (examples/jsonnet-snippets/bootkube.jsonnet)
 ```jsonnet
-(import 'kube-prometheus/kube-prometheus.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-bootkube.libsonnet')
+(import 'kube-prometheus/main.libsonnet') +
+(import 'kube-prometheus/platforms/bootkube.libsonnet')
 ```
 
 kops:
 
 [embedmd]:# (examples/jsonnet-snippets/kops.jsonnet)
 ```jsonnet
-(import 'kube-prometheus/kube-prometheus.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-kops.libsonnet')
+(import 'kube-prometheus/main.libsonnet') +
+(import 'kube-prometheus/platforms/kops.libsonnet')
 ```
 
 kops with CoreDNS:
@@ -439,25 +439,25 @@ If your kops cluster is using CoreDNS, there is an additional mixin to import.
 
 [embedmd]:# (examples/jsonnet-snippets/kops-coredns.jsonnet)
 ```jsonnet
-(import 'kube-prometheus/kube-prometheus.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-kops.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-kops-coredns.libsonnet')
+(import 'kube-prometheus/main.libsonnet') +
+(import 'kube-prometheus/platforms/kops.libsonnet') +
+(import 'kube-prometheus/platforms/kops-coredns.libsonnet')
 ```
 
 kubespray:
 
 [embedmd]:# (examples/jsonnet-snippets/kubespray.jsonnet)
 ```jsonnet
-(import 'kube-prometheus/kube-prometheus.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-kubespray.libsonnet')
+(import 'kube-prometheus/main.libsonnet') +
+(import 'kube-prometheus/platforms/kubespray.libsonnet')
 ```
 
-kube-aws:
+aws:
 
-[embedmd]:# (examples/jsonnet-snippets/kube-aws.jsonnet)
+[embedmd]:# (examples/jsonnet-snippets/aws.jsonnet)
 ```jsonnet
-(import 'kube-prometheus/kube-prometheus.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-kube-aws.libsonnet')
+(import 'kube-prometheus/main.libsonnet') +
+(import 'kube-prometheus/platforms/aws.libsonnet')
 ```
 
 ### Internal Registry
@@ -483,10 +483,12 @@ Then to generate manifests with `internal-registry.com/organization`, use the `w
 
 [embedmd]:# (examples/internal-registry.jsonnet)
 ```jsonnet
-local mixin = import 'kube-prometheus/kube-prometheus-config-mixins.libsonnet';
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local mixin = import 'kube-prometheus/addons/config-mixins.libsonnet';
+local kp = (import 'kube-prometheus/main.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
   },
 } + mixin.withImageRepository('internal-registry.com/organization');
 
@@ -505,8 +507,8 @@ Another mixin that may be useful for exploring the stack is to expose the UIs of
 
 [embedmd]:# (examples/jsonnet-snippets/node-ports.jsonnet)
 ```jsonnet
-(import 'kube-prometheus/kube-prometheus.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-node-ports.libsonnet')
+(import 'kube-prometheus/main.libsonnet') +
+(import 'kube-prometheus/addons/node-ports.libsonnet')
 ```
 
 ### Prometheus Object Name
@@ -515,7 +517,7 @@ To give another customization example, the name of the `Prometheus` object provi
 
 [embedmd]:# (examples/prometheus-name-override.jsonnet)
 ```jsonnet
-((import 'kube-prometheus/kube-prometheus.libsonnet') + {
+((import 'kube-prometheus/main.libsonnet') + {
    prometheus+: {
      prometheus+: {
        metadata+: {
@@ -532,7 +534,7 @@ Standard Kubernetes manifests are all written using [ksonnet-lib](https://github
 
 [embedmd]:# (examples/ksonnet-example.jsonnet)
 ```jsonnet
-((import 'kube-prometheus/kube-prometheus.libsonnet') + {
+((import 'kube-prometheus/main.libsonnet') + {
    nodeExporter+: {
      daemonset+: {
        metadata+: {
@@ -549,8 +551,8 @@ The Alertmanager configuration is located in the `_config.alertmanager.config` c
 
 [embedmd]:# (examples/alertmanager-config.jsonnet)
 ```jsonnet
-((import 'kube-prometheus/kube-prometheus.libsonnet') + {
-   _config+:: {
+((import 'kube-prometheus/main.libsonnet') + {
+   values+:: {
      alertmanager+: {
        config: |||
          global:
@@ -577,7 +579,7 @@ In the above example the configuration has been inlined, but can just as well be
 
 [embedmd]:# (examples/alertmanager-config-external.jsonnet)
 ```jsonnet
-((import 'kube-prometheus/kube-prometheus.libsonnet') + {
+((import 'kube-prometheus/main.libsonnet') + {
    _config+:: {
      alertmanager+: {
        config: importstr 'alertmanager-config.yaml',
@@ -592,9 +594,11 @@ In order to monitor additional namespaces, the Prometheus server requires the ap
 
 [embedmd]:# (examples/additional-namespaces.jsonnet)
 ```jsonnet
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
 
     prometheus+:: {
       namespaces+: ['my-namespace', 'my-second-namespace'],
@@ -621,14 +625,16 @@ You can define ServiceMonitor resources in your `jsonnet` spec. See the snippet
 
 [embedmd]:# (examples/additional-namespaces-servicemonitor.jsonnet)
 ```jsonnet
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
     prometheus+:: {
       namespaces+: ['my-namespace', 'my-second-namespace'],
     },
   },
-  prometheus+:: {
+  prometheus+: {
     serviceMonitorMyNamespace: {
       apiVersion: 'monitoring.coreos.com/v1',
       kind: 'ServiceMonitor',
@@ -671,12 +677,13 @@ In case you want to monitor all namespaces in a cluster, you can add the followi
 
 [embedmd]:# (examples/all-namespaces.jsonnet)
 ```jsonnet
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
-           (import 'kube-prometheus/kube-prometheus-all-namespaces.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
-
-    prometheus+:: {
+local kp = (import 'kube-prometheus/main.libsonnet') +
+           (import 'kube-prometheus/addons/all-namespaces.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
+    prometheus+: {
       namespaces: [],
     },
   },
@@ -718,10 +725,12 @@ To do that, one can import the following mixin
 
 [embedmd]:# (examples/strip-limits.jsonnet)
 ```jsonnet
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
-           (import 'kube-prometheus/kube-prometheus-strip-limits.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') +
+           (import 'kube-prometheus/addons/strip-limits.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
   },
 };
 
diff --git a/docs/EKS-cni-support.md b/docs/EKS-cni-support.md
index fb559d7845700770e462bc1c9cc0cb99e877a50c..4cb36bc975ea9b4351a403eb34f9fb8233ac219b 100644
--- a/docs/EKS-cni-support.md
+++ b/docs/EKS-cni-support.md
@@ -7,23 +7,29 @@ One fatal issue that can occur is that you run out of IP addresses in your eks c
 You can monitor the `awscni` using kube-promethus with : 
 [embedmd]:# (../examples/eks-cni-example.jsonnet)
 ```jsonnet
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
-           (import 'kube-prometheus/kube-prometheus-eks.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') +
+           (import 'kube-prometheus/platforms/eks.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
   },
-  prometheusRules+:: {
-    groups+: [
-      {
-        name: 'example-group',
-        rules: [
+  prometheus+: {
+    prometheusRuleEksCNI+: {
+      spec+: {
+        groups+: [
           {
-            record: 'aws_eks_available_ip',
-            expr: 'sum by(instance) (awscni_total_ip_addresses) - sum by(instance) (awscni_assigned_ip_addresses) < 10',
+            name: 'example-group',
+            rules: [
+              {
+                record: 'aws_eks_available_ip',
+                expr: 'sum by(instance) (awscni_total_ip_addresses) - sum by(instance) (awscni_assigned_ip_addresses) < 10',
+              },
+            ],
           },
         ],
       },
-    ],
+    },
   },
 };
 
diff --git a/docs/developing-prometheus-rules-and-grafana-dashboards.md b/docs/developing-prometheus-rules-and-grafana-dashboards.md
index b6c9f978359b6ac9dce30de46a8bf5983a5f2d38..31babf72a80cf03e9005c6ed049b59b5207e38fe 100644
--- a/docs/developing-prometheus-rules-and-grafana-dashboards.md
+++ b/docs/developing-prometheus-rules-and-grafana-dashboards.md
@@ -11,15 +11,15 @@ As a basis, all examples in this guide are based on the base example of the kube
 [embedmd]:# (../example.jsonnet)
 ```jsonnet
 local kp =
-  (import 'kube-prometheus/kube-prometheus.libsonnet') +
+  (import 'kube-prometheus/main.libsonnet') +
   // Uncomment the following imports to enable its patches
-  // (import 'kube-prometheus/kube-prometheus-anti-affinity.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-managed-cluster.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-node-ports.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-thanos-sidecar.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-custom-metrics.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-external-metrics.libsonnet') +
+  // (import 'kube-prometheus/addons/anti-affinity.libsonnet') +
+  // (import 'kube-prometheus/addons/managed-cluster.libsonnet') +
+  // (import 'kube-prometheus/addons/node-ports.libsonnet') +
+  // (import 'kube-prometheus/addons/static-etcd.libsonnet') +
+  // (import 'kube-prometheus/addons/thanos-sidecar.libsonnet') +
+  // (import 'kube-prometheus/addons/custom-metrics.libsonnet') +
+  // (import 'kube-prometheus/addons/external-metrics.libsonnet') +
   {
     values+:: {
       common+: {
@@ -37,14 +37,14 @@ local kp =
 { 'prometheus-operator-serviceMonitor': kp.prometheusOperator.serviceMonitor } +
 { 'prometheus-operator-prometheusRule': kp.prometheusOperator.prometheusRule } +
 { 'kube-prometheus-prometheusRule': kp.kubePrometheus.prometheusRule } +
-{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
-{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) } +
-{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
 { ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
-{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
-{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +
+{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) } +
 { ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
+{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
 { ['kubernetes-' + name]: kp.kubernetesMixin[name] for name in std.objectFields(kp.kubernetesMixin) }
+{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
+{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
+{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) }
 ```
 
 ## Prometheus rules
@@ -59,28 +59,34 @@ The format is exactly the Prometheus format, so there should be no changes neces
 
 [embedmd]:# (../examples/prometheus-additional-alert-rule-example.jsonnet)
 ```jsonnet
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
   },
-  prometheusAlerts+:: {
-    groups+: [
-      {
-        name: 'example-group',
-        rules: [
+  prometheus+: {
+    prometheusRule+: {
+      spec+: {
+        groups+: [
           {
-            alert: 'Watchdog',
-            expr: 'vector(1)',
-            labels: {
-              severity: 'none',
-            },
-            annotations: {
-              description: 'This is a Watchdog meant to ensure that the entire alerting pipeline is functional.',
-            },
+            name: 'example-group',
+            rules: [
+              {
+                alert: 'Watchdog',
+                expr: 'vector(1)',
+                labels: {
+                  severity: 'none',
+                },
+                annotations: {
+                  description: 'This is a Watchdog meant to ensure that the entire alerting pipeline is functional.',
+                },
+              },
+            ],
           },
         ],
       },
-    ],
+    },
   },
 };
 
@@ -102,22 +108,28 @@ In order to add a recording rule, simply do the same with the `prometheusRules`
 
 [embedmd]:# (../examples/prometheus-additional-recording-rule-example.jsonnet)
 ```jsonnet
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
   },
-  prometheusRules+:: {
-    groups+: [
-      {
-        name: 'example-group',
-        rules: [
+  prometheus+: {
+    prometheusRule+: {
+      spec+: {
+        groups+: [
           {
-            record: 'some_recording_rule_name',
-            expr: 'vector(1)',
+            name: 'example-group',
+            rules: [
+              {
+                record: 'some_recording_rule_name',
+                expr: 'vector(1)',
+              },
+            ],
           },
         ],
       },
-    ],
+    },
   },
 };
 
@@ -149,12 +161,18 @@ Then import it in jsonnet:
 
 [embedmd]:# (../examples/prometheus-additional-rendered-rule-example.jsonnet)
 ```jsonnet
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
   },
-  prometheusAlerts+:: {
-    groups+: (import 'existingrule.json').groups,
+  prometheus+: {
+    prometheusRule+: {
+      spec+: {
+        groups+: (import 'existingrule.json').groups,
+      },
+    },
   },
 };
 
@@ -255,7 +273,7 @@ local prometheus = grafana.prometheus;
 local template = grafana.template;
 local graphPanel = grafana.graphPanel;
 
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
+local kp = (import 'kube-prometheus/main.libsonnet') + {
   _config+:: {
     namespace: 'monitoring',
   },
@@ -303,7 +321,7 @@ As jsonnet is a superset of json, the jsonnet `import` function can be used to i
 
 [embedmd]:# (../examples/grafana-additional-rendered-dashboard-example.jsonnet)
 ```jsonnet
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
+local kp = (import 'kube-prometheus/main.libsonnet') + {
   _config+:: {
     namespace: 'monitoring',
   },
@@ -329,7 +347,7 @@ local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
 In case you have lots of json dashboard exported out from grafana UI the above approach is going to take lots of time to improve performance we can use `rawDashboards` field and provide it's value as json string by using `importstr`
 [embedmd]:# (../examples/grafana-additional-rendered-dashboard-example-2.jsonnet)
 ```jsonnet
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
+local kp = (import 'kube-prometheus/main.libsonnet') + {
   _config+:: {
     namespace: 'monitoring',
   },
diff --git a/docs/weave-net-support.md b/docs/weave-net-support.md
index 9924434a6c98d6ccb283ccaf6a2384aa44f34109..8766bfc8388bf77e8ad5d6813895286166028621 100644
--- a/docs/weave-net-support.md
+++ b/docs/weave-net-support.md
@@ -17,36 +17,42 @@ Using kube-prometheus and kubectl you will be able install the following for mon
 
 [embedmd]:# (../examples/weave-net-example.jsonnet)
 ```jsonnet
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
-           (import 'kube-prometheus/kube-prometheus-weave-net.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') +
+           (import 'kube-prometheus/addons/weave-net/weave-net.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
   },
-  prometheusAlerts+:: {
-    groups: std.map(
-      function(group)
-        if group.name == 'weave-net' then
-          group {
-            rules: std.map(
-              function(rule)
-                if rule.alert == 'WeaveNetFastDPFlowsLow' then
-                  rule {
-                    expr: 'sum(weave_flows) < 20000',
-                  }
-                else if rule.alert == 'WeaveNetIPAMUnreachable' then
-                  rule {
-                    expr: 'weave_ipam_unreachable_percentage > 25',
-                  }
-                else
-                  rule
-              ,
-              group.rules
-            ),
-          }
-        else
-          group,
-      super.groups
-    ),
+  prometheus+: {
+    prometheusRuleWeaveNet+: {
+      spec+: {
+        groups: std.map(
+          function(group)
+            if group.name == 'weave-net' then
+              group {
+                rules: std.map(
+                  function(rule)
+                    if rule.alert == 'WeaveNetFastDPFlowsLow' then
+                      rule {
+                        expr: 'sum(weave_flows) < 20000',
+                      }
+                    else if rule.alert == 'WeaveNetIPAMUnreachable' then
+                      rule {
+                        expr: 'weave_ipam_unreachable_percentage > 25',
+                      }
+                    else
+                      rule
+                  ,
+                  group.rules
+                ),
+              }
+            else
+              group,
+          super.groups
+        ),
+      },
+    },
   },
 };
 
diff --git a/example.jsonnet b/example.jsonnet
index c3c496b905945308ddbbb78faa3f29cbd7cd6dfd..2568be96826783214cb50e4903e2c6895ee69575 100644
--- a/example.jsonnet
+++ b/example.jsonnet
@@ -1,13 +1,13 @@
 local kp =
-  (import 'kube-prometheus/kube-prometheus.libsonnet') +
+  (import 'kube-prometheus/main.libsonnet') +
   // Uncomment the following imports to enable its patches
-  // (import 'kube-prometheus/kube-prometheus-anti-affinity.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-managed-cluster.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-node-ports.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-thanos-sidecar.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-custom-metrics.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-external-metrics.libsonnet') +
+  // (import 'kube-prometheus/addons/anti-affinity.libsonnet') +
+  // (import 'kube-prometheus/addons/managed-cluster.libsonnet') +
+  // (import 'kube-prometheus/addons/node-ports.libsonnet') +
+  // (import 'kube-prometheus/addons/static-etcd.libsonnet') +
+  // (import 'kube-prometheus/addons/thanos-sidecar.libsonnet') +
+  // (import 'kube-prometheus/addons/custom-metrics.libsonnet') +
+  // (import 'kube-prometheus/addons/external-metrics.libsonnet') +
   {
     values+:: {
       common+: {
@@ -25,11 +25,11 @@ local kp =
 { 'prometheus-operator-serviceMonitor': kp.prometheusOperator.serviceMonitor } +
 { 'prometheus-operator-prometheusRule': kp.prometheusOperator.prometheusRule } +
 { 'kube-prometheus-prometheusRule': kp.kubePrometheus.prometheusRule } +
-{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
-{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) } +
-{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
 { ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
-{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
-{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +
+{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) } +
 { ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
+{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
 { ['kubernetes-' + name]: kp.kubernetesMixin[name] for name in std.objectFields(kp.kubernetesMixin) }
+{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
+{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
+{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) }
diff --git a/examples/additional-namespaces-servicemonitor.jsonnet b/examples/additional-namespaces-servicemonitor.jsonnet
index 0f3add96d462392f903fbf64276d3c42f822f459..6cfe37dbd337aa85815e0660a09d0cb6e964ce8e 100644
--- a/examples/additional-namespaces-servicemonitor.jsonnet
+++ b/examples/additional-namespaces-servicemonitor.jsonnet
@@ -1,11 +1,13 @@
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
     prometheus+:: {
       namespaces+: ['my-namespace', 'my-second-namespace'],
     },
   },
-  prometheus+:: {
+  prometheus+: {
     serviceMonitorMyNamespace: {
       apiVersion: 'monitoring.coreos.com/v1',
       kind: 'ServiceMonitor',
diff --git a/examples/additional-namespaces.jsonnet b/examples/additional-namespaces.jsonnet
index 957fd9124741ef75acf4541fe5bfaeea52e4b55d..85cae475e97f772c11e77e488ea4d6f2b455b848 100644
--- a/examples/additional-namespaces.jsonnet
+++ b/examples/additional-namespaces.jsonnet
@@ -1,6 +1,8 @@
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
 
     prometheus+:: {
       namespaces+: ['my-namespace', 'my-second-namespace'],
diff --git a/examples/alertmanager-config-external.jsonnet b/examples/alertmanager-config-external.jsonnet
index c2b34ccaa36892ce5a0fa28ff1947083d5d93167..5d96d23dec49fc7918f0ddc10f6d13d03cc8ecc7 100644
--- a/examples/alertmanager-config-external.jsonnet
+++ b/examples/alertmanager-config-external.jsonnet
@@ -1,4 +1,4 @@
-((import 'kube-prometheus/kube-prometheus.libsonnet') + {
+((import 'kube-prometheus/main.libsonnet') + {
    _config+:: {
      alertmanager+: {
        config: importstr 'alertmanager-config.yaml',
diff --git a/examples/alertmanager-config.jsonnet b/examples/alertmanager-config.jsonnet
index f08dbe19e333073d6553fda87bf5b4671787c0ac..9702711aead46d011c90e097dcb818d826bf8c66 100644
--- a/examples/alertmanager-config.jsonnet
+++ b/examples/alertmanager-config.jsonnet
@@ -1,5 +1,5 @@
-((import 'kube-prometheus/kube-prometheus.libsonnet') + {
-   _config+:: {
+((import 'kube-prometheus/main.libsonnet') + {
+   values+:: {
      alertmanager+: {
        config: |||
          global:
diff --git a/examples/all-namespaces.jsonnet b/examples/all-namespaces.jsonnet
index 7c5d149f1473ae4a856bbf386845562b594aa15f..52534766efa4d2b3f7dc4741a72936d7f7f8340a 100644
--- a/examples/all-namespaces.jsonnet
+++ b/examples/all-namespaces.jsonnet
@@ -1,9 +1,10 @@
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
-           (import 'kube-prometheus/kube-prometheus-all-namespaces.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
-
-    prometheus+:: {
+local kp = (import 'kube-prometheus/main.libsonnet') +
+           (import 'kube-prometheus/addons/all-namespaces.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
+    prometheus+: {
       namespaces: [],
     },
   },
diff --git a/examples/continuous-delivery/argocd/kube-prometheus/argocd-basic.jsonnet b/examples/continuous-delivery/argocd/kube-prometheus/argocd-basic.jsonnet
index 8600d818df6065823be4252f871f9b4902ffd471..94089e0c948155a390b595f130d5f16eae691cae 100644
--- a/examples/continuous-delivery/argocd/kube-prometheus/argocd-basic.jsonnet
+++ b/examples/continuous-delivery/argocd/kube-prometheus/argocd-basic.jsonnet
@@ -1,7 +1,8 @@
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
-
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
   },
 };
 
diff --git a/examples/eks-cni-example.jsonnet b/examples/eks-cni-example.jsonnet
index dcebf6ddcd56240e26d66a84eb378e4566cf003d..77fa5d0bed42b5d564a3eb47b5bdd8a75b155d71 100644
--- a/examples/eks-cni-example.jsonnet
+++ b/examples/eks-cni-example.jsonnet
@@ -1,20 +1,26 @@
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
-           (import 'kube-prometheus/kube-prometheus-eks.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') +
+           (import 'kube-prometheus/platforms/eks.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
   },
-  prometheusRules+:: {
-    groups+: [
-      {
-        name: 'example-group',
-        rules: [
+  prometheus+: {
+    prometheusRuleEksCNI+: {
+      spec+: {
+        groups+: [
           {
-            record: 'aws_eks_available_ip',
-            expr: 'sum by(instance) (awscni_total_ip_addresses) - sum by(instance) (awscni_assigned_ip_addresses) < 10',
+            name: 'example-group',
+            rules: [
+              {
+                record: 'aws_eks_available_ip',
+                expr: 'sum by(instance) (awscni_total_ip_addresses) - sum by(instance) (awscni_assigned_ip_addresses) < 10',
+              },
+            ],
           },
         ],
       },
-    ],
+    },
   },
 };
 
diff --git a/examples/etcd-skip-verify.jsonnet b/examples/etcd-skip-verify.jsonnet
index 603ba710e48a5cefd0c2c80df0796fb2e5ce5484..9982fa1699eb6ebf995f1bb927362f977511cec1 100644
--- a/examples/etcd-skip-verify.jsonnet
+++ b/examples/etcd-skip-verify.jsonnet
@@ -1,8 +1,9 @@
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
-           (import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
-
+local kp = (import 'kube-prometheus/main.libsonnet') +
+           (import 'kube-prometheus/addons/static-etcd.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
     etcd+:: {
       ips: ['127.0.0.1'],
       clientCA: importstr 'etcd-client-ca.crt',
diff --git a/examples/etcd.jsonnet b/examples/etcd.jsonnet
index 03d390cddb69fadd3c575bc97d14557def5fa531..e494b6ad20ffe94f5713b2b49f43b9d0911be864 100644
--- a/examples/etcd.jsonnet
+++ b/examples/etcd.jsonnet
@@ -1,7 +1,9 @@
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
-           (import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') +
+           (import 'kube-prometheus/addons/static-etcd.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
 
     // Reference info: https://github.com/coreos/kube-prometheus/blob/master/README.md#static-etcd-configuration
     etcd+:: {
diff --git a/examples/grafana-additional-jsonnet-dashboard-example.jsonnet b/examples/grafana-additional-jsonnet-dashboard-example.jsonnet
index b9b26fca552e983ab74d3ea2505240cb0892700e..fcfdd1fb4a90e859e1617cf25c2177cca10796a6 100644
--- a/examples/grafana-additional-jsonnet-dashboard-example.jsonnet
+++ b/examples/grafana-additional-jsonnet-dashboard-example.jsonnet
@@ -5,7 +5,7 @@ local prometheus = grafana.prometheus;
 local template = grafana.template;
 local graphPanel = grafana.graphPanel;
 
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
+local kp = (import 'kube-prometheus/main.libsonnet') + {
   _config+:: {
     namespace: 'monitoring',
   },
diff --git a/examples/grafana-additional-rendered-dashboard-example-2.jsonnet b/examples/grafana-additional-rendered-dashboard-example-2.jsonnet
index 7d0926e99c05885cc1a0dbf1950c50b59db1a4d3..e18c6242479a1213ce3e2e6b3bb5460916eaaad2 100644
--- a/examples/grafana-additional-rendered-dashboard-example-2.jsonnet
+++ b/examples/grafana-additional-rendered-dashboard-example-2.jsonnet
@@ -1,4 +1,4 @@
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
+local kp = (import 'kube-prometheus/main.libsonnet') + {
   _config+:: {
     namespace: 'monitoring',
   },
diff --git a/examples/grafana-additional-rendered-dashboard-example.jsonnet b/examples/grafana-additional-rendered-dashboard-example.jsonnet
index 883c609700a8e9c6ccdf19ad6d068d9a55c778a5..6c5bb0489cc9d8f971d444e609506a63002613af 100644
--- a/examples/grafana-additional-rendered-dashboard-example.jsonnet
+++ b/examples/grafana-additional-rendered-dashboard-example.jsonnet
@@ -1,4 +1,4 @@
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
+local kp = (import 'kube-prometheus/main.libsonnet') + {
   _config+:: {
     namespace: 'monitoring',
   },
diff --git a/examples/ingress.jsonnet b/examples/ingress.jsonnet
index 023af577bafad7dddf6a76184108138861cb47d3..a2e26cd7e5d7075f318ec15858fa4ec6a02fd3d4 100644
--- a/examples/ingress.jsonnet
+++ b/examples/ingress.jsonnet
@@ -14,10 +14,12 @@ local ingress(name, namespace, rules) = {
 };
 
 local kp =
-  (import 'kube-prometheus/kube-prometheus.libsonnet') +
+  (import 'kube-prometheus/main.libsonnet') +
   {
-    _config+:: {
-      namespace: 'monitoring',
+    values+:: {
+      common+: {
+        namespace: 'monitoring',
+      },
       grafana+:: {
         config+: {
           sections+: {
@@ -47,7 +49,7 @@ local kp =
     ingress+:: {
       'alertmanager-main': ingress(
         'alertmanager-main',
-        $._config.namespace,
+        $.values.common.namespace,
         [{
           host: 'alertmanager.example.com',
           http: {
@@ -64,7 +66,7 @@ local kp =
       ),
       grafana: ingress(
         'grafana',
-        $._config.namespace,
+        $.values.common.namespace,
         [{
           host: 'grafana.example.com',
           http: {
@@ -81,7 +83,7 @@ local kp =
       ),
       'prometheus-k8s': ingress(
         'prometheus-k8s',
-        $._config.namespace,
+        $.values.common.namespace,
         [{
           host: 'prometheus.example.com',
           http: {
@@ -105,7 +107,7 @@ local kp =
         kind: 'Secret',
         metadata: {
           name: 'basic-auth',
-          namespace: $._config.namespace,
+          namespace: $.values.common.namespace,
         },
         data: { auth: std.base64(importstr 'auth') },
         type: 'Opaque',
diff --git a/examples/internal-registry.jsonnet b/examples/internal-registry.jsonnet
index f1d1e8ac9e49774b16cc4b97a5803f67b0f790c2..fc470de61da6e5e140aafa53fdd8f172b4630539 100644
--- a/examples/internal-registry.jsonnet
+++ b/examples/internal-registry.jsonnet
@@ -1,7 +1,9 @@
-local mixin = import 'kube-prometheus/kube-prometheus-config-mixins.libsonnet';
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local mixin = import 'kube-prometheus/addons/config-mixins.libsonnet';
+local kp = (import 'kube-prometheus/main.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
   },
 } + mixin.withImageRepository('internal-registry.com/organization');
 
diff --git a/examples/jsonnet-snippets/aws.jsonnet b/examples/jsonnet-snippets/aws.jsonnet
new file mode 100644
index 0000000000000000000000000000000000000000..6eaca09ff8941bfabefc0a963566cc9316f0c395
--- /dev/null
+++ b/examples/jsonnet-snippets/aws.jsonnet
@@ -0,0 +1,2 @@
+(import 'kube-prometheus/main.libsonnet') +
+(import 'kube-prometheus/platforms/aws.libsonnet')
diff --git a/examples/jsonnet-snippets/bootkube.jsonnet b/examples/jsonnet-snippets/bootkube.jsonnet
index f7386a012ab6e8594d6d833aee3264e5e40caf7d..3d9f3482f86cdcd48591ed4eb9bbf8d502ad78e6 100644
--- a/examples/jsonnet-snippets/bootkube.jsonnet
+++ b/examples/jsonnet-snippets/bootkube.jsonnet
@@ -1,2 +1,2 @@
-(import 'kube-prometheus/kube-prometheus.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-bootkube.libsonnet')
+(import 'kube-prometheus/main.libsonnet') +
+(import 'kube-prometheus/platforms/bootkube.libsonnet')
diff --git a/examples/jsonnet-snippets/kops-coredns.jsonnet b/examples/jsonnet-snippets/kops-coredns.jsonnet
index 6ba445dff751e10c8c52e2c7c57dd08eb43cd6e9..d1af478b73240a1d5585022b34f1b87f512f7023 100644
--- a/examples/jsonnet-snippets/kops-coredns.jsonnet
+++ b/examples/jsonnet-snippets/kops-coredns.jsonnet
@@ -1,3 +1,3 @@
-(import 'kube-prometheus/kube-prometheus.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-kops.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-kops-coredns.libsonnet')
+(import 'kube-prometheus/main.libsonnet') +
+(import 'kube-prometheus/platforms/kops.libsonnet') +
+(import 'kube-prometheus/platforms/kops-coredns.libsonnet')
diff --git a/examples/jsonnet-snippets/kops.jsonnet b/examples/jsonnet-snippets/kops.jsonnet
index 4ff9ceaea1f8dca3b474d0cb5d1f4e6d895a71ea..9271b993d38e35c0161e6d88fa1214c6a94e9518 100644
--- a/examples/jsonnet-snippets/kops.jsonnet
+++ b/examples/jsonnet-snippets/kops.jsonnet
@@ -1,2 +1,2 @@
-(import 'kube-prometheus/kube-prometheus.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-kops.libsonnet')
+(import 'kube-prometheus/main.libsonnet') +
+(import 'kube-prometheus/platforms/kops.libsonnet')
diff --git a/examples/jsonnet-snippets/kube-aws.jsonnet b/examples/jsonnet-snippets/kube-aws.jsonnet
deleted file mode 100644
index b0842eb24e1dde19565afd6ae88ff52dab819b26..0000000000000000000000000000000000000000
--- a/examples/jsonnet-snippets/kube-aws.jsonnet
+++ /dev/null
@@ -1,2 +0,0 @@
-(import 'kube-prometheus/kube-prometheus.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-kube-aws.libsonnet')
diff --git a/examples/jsonnet-snippets/kubeadm.jsonnet b/examples/jsonnet-snippets/kubeadm.jsonnet
index a7837163e4ffe9cae140382eae63dde0d2395321..0750b4b39bc1fb9ff6ce064da19cd0555edc60e7 100644
--- a/examples/jsonnet-snippets/kubeadm.jsonnet
+++ b/examples/jsonnet-snippets/kubeadm.jsonnet
@@ -1,2 +1,2 @@
-(import 'kube-prometheus/kube-prometheus.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-kubeadm.libsonnet')
+(import 'kube-prometheus/main.libsonnet') +
+(import 'kube-prometheus/platforms/kubeadm.libsonnet')
diff --git a/examples/jsonnet-snippets/kubespray.jsonnet b/examples/jsonnet-snippets/kubespray.jsonnet
index 1665cf7285921d27f4e445c68087ff6cd8a175f4..d9bb3bd51f4cd319b401d9d0062a7a38395dc79d 100644
--- a/examples/jsonnet-snippets/kubespray.jsonnet
+++ b/examples/jsonnet-snippets/kubespray.jsonnet
@@ -1,2 +1,2 @@
-(import 'kube-prometheus/kube-prometheus.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-kubespray.libsonnet')
+(import 'kube-prometheus/main.libsonnet') +
+(import 'kube-prometheus/platforms/kubespray.libsonnet')
diff --git a/examples/jsonnet-snippets/node-ports.jsonnet b/examples/jsonnet-snippets/node-ports.jsonnet
index c02f1ae729edd7f8fb9df8f39d8a8f2a68c600c7..abc70c94b4832887ee564ac697f82ea8ff382e9f 100644
--- a/examples/jsonnet-snippets/node-ports.jsonnet
+++ b/examples/jsonnet-snippets/node-ports.jsonnet
@@ -1,2 +1,2 @@
-(import 'kube-prometheus/kube-prometheus.libsonnet') +
-(import 'kube-prometheus/kube-prometheus-node-ports.libsonnet')
+(import 'kube-prometheus/main.libsonnet') +
+(import 'kube-prometheus/addons/node-ports.libsonnet')
diff --git a/examples/ksonnet-example.jsonnet b/examples/ksonnet-example.jsonnet
index eadd2cb79c7309558abece9a1a05747cf7359366..36640ab4309282810785c58cb6a1c91e9f59bdd5 100644
--- a/examples/ksonnet-example.jsonnet
+++ b/examples/ksonnet-example.jsonnet
@@ -1,4 +1,4 @@
-((import 'kube-prometheus/kube-prometheus.libsonnet') + {
+((import 'kube-prometheus/main.libsonnet') + {
    nodeExporter+: {
      daemonset+: {
        metadata+: {
diff --git a/examples/kustomize.jsonnet b/examples/kustomize.jsonnet
index 875d3501256ec30f9ff18e5fcbd21068eb37a2f8..ab548b05f37088b364ccdc5f022ac1304cd24052 100644
--- a/examples/kustomize.jsonnet
+++ b/examples/kustomize.jsonnet
@@ -1,5 +1,5 @@
 local kp =
-  (import 'kube-prometheus/kube-prometheus.libsonnet') + {
+  (import 'kube-prometheus/main.libsonnet') + {
     values+:: {
       common+: {
         namespace: 'monitoring',
diff --git a/examples/minikube.jsonnet b/examples/minikube.jsonnet
index 3073612a4849c849d0e366c366795edbed243c7b..dd2f77b42dc9987f48ee8b44c89c4d1f0fdcf0be 100644
--- a/examples/minikube.jsonnet
+++ b/examples/minikube.jsonnet
@@ -1,11 +1,13 @@
 local kp =
-  (import 'kube-prometheus/kube-prometheus.libsonnet') +
-  (import 'kube-prometheus/kube-prometheus-kubeadm.libsonnet') +
+  (import 'kube-prometheus/main.libsonnet') +
+  (import 'kube-prometheus/platforms/kubeadm.libsonnet') +
   // Note that NodePort type services is likely not a good idea for your production use case, it is only used for demonstration purposes here.
-  (import 'kube-prometheus/kube-prometheus-node-ports.libsonnet') +
+  (import 'kube-prometheus/addons/node-ports.libsonnet') +
   {
-    _config+:: {
-      namespace: 'monitoring',
+    values+:: {
+      common+: {
+        namespace: 'monitoring',
+      },
       alertmanager+:: {
         config: importstr 'alertmanager-config.yaml',
       },
@@ -22,7 +24,7 @@ local kp =
     // For simplicity, each of the following values for 'externalUrl':
     //  * assume that `minikube ip` prints "192.168.99.100"
     //  * hard-code the NodePort for each app
-    prometheus+:: {
+    prometheus+: {
       prometheus+: {
         // Reference info: https://coreos.com/operators/prometheus/docs/latest/api.html#prometheusspec
         spec+: {
diff --git a/examples/prometheus-additional-alert-rule-example.jsonnet b/examples/prometheus-additional-alert-rule-example.jsonnet
index 6e63382e20e97b43d9342562cda2c0981706b766..63ec2ea740944ba0f8f6526a54e583067d8c3a51 100644
--- a/examples/prometheus-additional-alert-rule-example.jsonnet
+++ b/examples/prometheus-additional-alert-rule-example.jsonnet
@@ -1,25 +1,31 @@
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
   },
-  prometheusAlerts+:: {
-    groups+: [
-      {
-        name: 'example-group',
-        rules: [
+  prometheus+: {
+    prometheusRule+: {
+      spec+: {
+        groups+: [
           {
-            alert: 'Watchdog',
-            expr: 'vector(1)',
-            labels: {
-              severity: 'none',
-            },
-            annotations: {
-              description: 'This is a Watchdog meant to ensure that the entire alerting pipeline is functional.',
-            },
+            name: 'example-group',
+            rules: [
+              {
+                alert: 'Watchdog',
+                expr: 'vector(1)',
+                labels: {
+                  severity: 'none',
+                },
+                annotations: {
+                  description: 'This is a Watchdog meant to ensure that the entire alerting pipeline is functional.',
+                },
+              },
+            ],
           },
         ],
       },
-    ],
+    },
   },
 };
 
diff --git a/examples/prometheus-additional-recording-rule-example.jsonnet b/examples/prometheus-additional-recording-rule-example.jsonnet
index 132bd0db0f4a1b891385c455064c71068d35a94b..c2abc4d39c9b669b2deba19518cce8e59ae2fc1c 100644
--- a/examples/prometheus-additional-recording-rule-example.jsonnet
+++ b/examples/prometheus-additional-recording-rule-example.jsonnet
@@ -1,19 +1,25 @@
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
   },
-  prometheusRules+:: {
-    groups+: [
-      {
-        name: 'example-group',
-        rules: [
+  prometheus+: {
+    prometheusRule+: {
+      spec+: {
+        groups+: [
           {
-            record: 'some_recording_rule_name',
-            expr: 'vector(1)',
+            name: 'example-group',
+            rules: [
+              {
+                record: 'some_recording_rule_name',
+                expr: 'vector(1)',
+              },
+            ],
           },
         ],
       },
-    ],
+    },
   },
 };
 
diff --git a/examples/prometheus-additional-rendered-rule-example.jsonnet b/examples/prometheus-additional-rendered-rule-example.jsonnet
index b6d39a4052e168bc7f46fc1278eb32d9c48fe482..296768512d59e88cbee858833a52e7425cc5b5e1 100644
--- a/examples/prometheus-additional-rendered-rule-example.jsonnet
+++ b/examples/prometheus-additional-rendered-rule-example.jsonnet
@@ -1,9 +1,15 @@
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
   },
-  prometheusAlerts+:: {
-    groups+: (import 'existingrule.json').groups,
+  prometheus+: {
+    prometheusRule+: {
+      spec+: {
+        groups+: (import 'existingrule.json').groups,
+      },
+    },
   },
 };
 
diff --git a/examples/prometheus-name-override.jsonnet b/examples/prometheus-name-override.jsonnet
index 862180129d9f3440ccc158ea07e33bc440b22561..b6c3906059b88c938d60e84dd1a7f603fbfadbc5 100644
--- a/examples/prometheus-name-override.jsonnet
+++ b/examples/prometheus-name-override.jsonnet
@@ -1,4 +1,4 @@
-((import 'kube-prometheus/kube-prometheus.libsonnet') + {
+((import 'kube-prometheus/main.libsonnet') + {
    prometheus+: {
      prometheus+: {
        metadata+: {
diff --git a/examples/prometheus-pvc.jsonnet b/examples/prometheus-pvc.jsonnet
index e753499e17b273a588875332634af842410acc2e..ee0f5c245afbfca3dbf12b12637b2666298b8fa0 100644
--- a/examples/prometheus-pvc.jsonnet
+++ b/examples/prometheus-pvc.jsonnet
@@ -1,14 +1,16 @@
 local kp =
-  (import 'kube-prometheus/kube-prometheus.libsonnet') +
+  (import 'kube-prometheus/main.libsonnet') +
   // Uncomment the following imports to enable its patches
-  // (import 'kube-prometheus/kube-prometheus-anti-affinity.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-managed-cluster.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-node-ports.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') +
-  // (import 'kube-prometheus/kube-prometheus-thanos-sidecar.libsonnet') +
+  // (import 'kube-prometheus/addons/anti-affinity.libsonnet') +
+  // (import 'kube-prometheus/addons/managed-cluster.libsonnet') +
+  // (import 'kube-prometheus/addons/node-ports.libsonnet') +
+  // (import 'kube-prometheus/addons/static-etcd.libsonnet') +
+  // (import 'kube-prometheus/addons/thanos-sidecar.libsonnet') +
   {
-    _config+:: {
-      namespace: 'monitoring',
+    values+:: {
+      common+: {
+        namespace: 'monitoring',
+      },
     },
 
     prometheus+:: {
diff --git a/examples/strip-limits.jsonnet b/examples/strip-limits.jsonnet
index 69912b648d471f4a97aad3a012436f65ba80dd1f..fc43e286066a0409388e5edd70c0c51ab9481aa6 100644
--- a/examples/strip-limits.jsonnet
+++ b/examples/strip-limits.jsonnet
@@ -1,7 +1,9 @@
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
-           (import 'kube-prometheus/kube-prometheus-strip-limits.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') +
+           (import 'kube-prometheus/addons/strip-limits.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
   },
 };
 
diff --git a/examples/tolerations.libsonnet b/examples/tolerations.libsonnet
index 35776f397b93813d56f709666014a4b703bd45da..f244cebf3a5e1d6684b46e678876a38ca60eb360 100644
--- a/examples/tolerations.libsonnet
+++ b/examples/tolerations.libsonnet
@@ -1,23 +1,19 @@
 {
-  _config+:: {
-    tolerations+:: [
-      {
-        key: 'key1',
-        operator: 'Equal',
-        value: 'value1',
-        effect: 'NoSchedule',
-      },
-      {
-        key: 'key2',
-        operator: 'Exists',
-      },
-    ],
-  },
-
   prometheus+: {
     prometheus+: {
       spec+: {
-        tolerations: [t for t in $._config.tolerations],
+        tolerations: [
+          {
+            key: 'key1',
+            operator: 'Equal',
+            value: 'value1',
+            effect: 'NoSchedule',
+          },
+          {
+            key: 'key2',
+            operator: 'Exists',
+          },
+        ],
       },
     },
   },
diff --git a/examples/weave-net-example.jsonnet b/examples/weave-net-example.jsonnet
index c6cc733c27a465b5ddd169d0314451d7d328950a..a7eca242c2402e53190d6d8906ed87785c519480 100644
--- a/examples/weave-net-example.jsonnet
+++ b/examples/weave-net-example.jsonnet
@@ -1,33 +1,39 @@
-local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
-           (import 'kube-prometheus/kube-prometheus-weave-net.libsonnet') + {
-  _config+:: {
-    namespace: 'monitoring',
+local kp = (import 'kube-prometheus/main.libsonnet') +
+           (import 'kube-prometheus/addons/weave-net/weave-net.libsonnet') + {
+  values+:: {
+    common+: {
+      namespace: 'monitoring',
+    },
   },
-  prometheusAlerts+:: {
-    groups: std.map(
-      function(group)
-        if group.name == 'weave-net' then
-          group {
-            rules: std.map(
-              function(rule)
-                if rule.alert == 'WeaveNetFastDPFlowsLow' then
-                  rule {
-                    expr: 'sum(weave_flows) < 20000',
-                  }
-                else if rule.alert == 'WeaveNetIPAMUnreachable' then
-                  rule {
-                    expr: 'weave_ipam_unreachable_percentage > 25',
-                  }
-                else
-                  rule
-              ,
-              group.rules
-            ),
-          }
-        else
-          group,
-      super.groups
-    ),
+  prometheus+: {
+    prometheusRuleWeaveNet+: {
+      spec+: {
+        groups: std.map(
+          function(group)
+            if group.name == 'weave-net' then
+              group {
+                rules: std.map(
+                  function(rule)
+                    if rule.alert == 'WeaveNetFastDPFlowsLow' then
+                      rule {
+                        expr: 'sum(weave_flows) < 20000',
+                      }
+                    else if rule.alert == 'WeaveNetIPAMUnreachable' then
+                      rule {
+                        expr: 'weave_ipam_unreachable_percentage > 25',
+                      }
+                    else
+                      rule
+                  ,
+                  group.rules
+                ),
+              }
+            else
+              group,
+          super.groups
+        ),
+      },
+    },
   },
 };
 
diff --git a/jsonnet/kube-prometheus/kube-prometheus-all-namespaces.libsonnet b/jsonnet/kube-prometheus/addons/all-namespaces.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/kube-prometheus-all-namespaces.libsonnet
rename to jsonnet/kube-prometheus/addons/all-namespaces.libsonnet
diff --git a/jsonnet/kube-prometheus/kube-prometheus-anti-affinity.libsonnet b/jsonnet/kube-prometheus/addons/anti-affinity.libsonnet
similarity index 79%
rename from jsonnet/kube-prometheus/kube-prometheus-anti-affinity.libsonnet
rename to jsonnet/kube-prometheus/addons/anti-affinity.libsonnet
index 6358236206fb982e1e8c58d65acd2bf072a10c32..014f32a900d33e4335d22b92eb3df2ea00c0a4ee 100644
--- a/jsonnet/kube-prometheus/kube-prometheus-anti-affinity.libsonnet
+++ b/jsonnet/kube-prometheus/addons/anti-affinity.libsonnet
@@ -25,14 +25,14 @@
   alertmanager+:: {
     alertmanager+: {
       spec+:
-        antiaffinity('alertmanager', [$._config.alertmanager.name], $._config.namespace),
+        antiaffinity('alertmanager', [$.values.alertmanager.name], $.values.common.namespace),
     },
   },
 
   prometheus+:: {
     prometheus+: {
       spec+:
-        antiaffinity('prometheus', [$._config.prometheus.name], $._config.namespace),
+        antiaffinity('prometheus', [$.values.prometheus.name], $.values.common.namespace),
     },
   },
 }
diff --git a/jsonnet/kube-prometheus/kube-prometheus-config-mixins.libsonnet b/jsonnet/kube-prometheus/addons/config-mixins.libsonnet
similarity index 55%
rename from jsonnet/kube-prometheus/kube-prometheus-config-mixins.libsonnet
rename to jsonnet/kube-prometheus/addons/config-mixins.libsonnet
index ff8fd2979f506e96ec0c464f4435a19044ed7c20..79f25044b1f8756293e40fd786d0cbc440353abd 100644
--- a/jsonnet/kube-prometheus/kube-prometheus-config-mixins.libsonnet
+++ b/jsonnet/kube-prometheus/addons/config-mixins.libsonnet
@@ -1,4 +1,18 @@
-local l = import 'lib/lib.libsonnet';
+local imageName(image) =
+  local parts = std.split(image, '/');
+  local len = std.length(parts);
+  if len == 3 then
+    // registry.com/org/image
+    parts[2]
+  else if len == 2 then
+    // org/image
+    parts[1]
+  else if len == 1 then
+    // image, ie. busybox
+    parts[0]
+  else
+    error 'unknown image format: ' + image;
+
 
 // withImageRepository is a mixin that replaces all images prefixes by repository. eg.
 // quay.io/coreos/addon-resizer -> $repository/addon-resizer
@@ -6,8 +20,8 @@ local l = import 'lib/lib.libsonnet';
 local withImageRepository(repository) = {
   local oldRepos = super._config.imageRepos,
   local substituteRepository(image, repository) =
-    if repository == null then image else repository + '/' + l.imageName(image),
-  _config+:: {
+    if repository == null then image else repository + '/' + imageName(image),
+  values+:: {
     imageRepos:: {
       [field]: substituteRepository(oldRepos[field], repository)
       for field in std.objectFields(oldRepos)
diff --git a/jsonnet/kube-prometheus/kube-prometheus-custom-metrics.libsonnet b/jsonnet/kube-prometheus/addons/custom-metrics.libsonnet
similarity index 94%
rename from jsonnet/kube-prometheus/kube-prometheus-custom-metrics.libsonnet
rename to jsonnet/kube-prometheus/addons/custom-metrics.libsonnet
index d98b133f93b925f88ab65d7a446e914a9605b4b0..06e9c5a0b22a53a4c56994fa40dd315281f899aa 100644
--- a/jsonnet/kube-prometheus/kube-prometheus-custom-metrics.libsonnet
+++ b/jsonnet/kube-prometheus/addons/custom-metrics.libsonnet
@@ -2,9 +2,9 @@
 // For more details on usage visit https://github.com/DirectXMan12/k8s-prometheus-adapter#quick-links
 
 {
-  _config+:: {
-    prometheusAdapter+:: {
-      namespace: $._config.namespace,
+  values+:: {
+    prometheusAdapter+: {
+      namespace: $.values.common.namespace,
       // Rules for custom-metrics
       config+:: {
         rules+: [
@@ -78,7 +78,7 @@
     },
   },
 
-  prometheusAdapter+:: {
+  prometheusAdapter+: {
     customMetricsApiService: {
       apiVersion: 'apiregistration.k8s.io/v1',
       kind: 'APIService',
@@ -88,7 +88,7 @@
       spec: {
         service: {
           name: $.prometheusAdapter.service.metadata.name,
-          namespace: $._config.prometheusAdapter.namespace,
+          namespace: $.values.prometheusAdapter.namespace,
         },
         group: 'custom.metrics.k8s.io',
         version: 'v1beta1',
@@ -106,7 +106,7 @@
       spec: {
         service: {
           name: $.prometheusAdapter.service.metadata.name,
-          namespace: $._config.prometheusAdapter.namespace,
+          namespace: $.values.prometheusAdapter.namespace,
         },
         group: 'custom.metrics.k8s.io',
         version: 'v1beta2',
@@ -141,7 +141,7 @@
       subjects: [{
         kind: 'ServiceAccount',
         name: $.prometheusAdapter.serviceAccount.metadata.name,
-        namespace: $._config.prometheusAdapter.namespace,
+        namespace: $.values.prometheusAdapter.namespace,
       }],
     },
     customMetricsClusterRoleBindingHPA: {
diff --git a/jsonnet/kube-prometheus/dropping-deprecated-metrics-relabelings.libsonnet b/jsonnet/kube-prometheus/addons/dropping-deprecated-metrics-relabelings.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/dropping-deprecated-metrics-relabelings.libsonnet
rename to jsonnet/kube-prometheus/addons/dropping-deprecated-metrics-relabelings.libsonnet
diff --git a/jsonnet/kube-prometheus/kube-prometheus-external-metrics.libsonnet b/jsonnet/kube-prometheus/addons/external-metrics.libsonnet
similarity index 91%
rename from jsonnet/kube-prometheus/kube-prometheus-external-metrics.libsonnet
rename to jsonnet/kube-prometheus/addons/external-metrics.libsonnet
index abe35b0c2881247a2b821d5a10e756bb6c8c2799..928d29e7248293dd06859cfb769b192ed6adc1ee 100644
--- a/jsonnet/kube-prometheus/kube-prometheus-external-metrics.libsonnet
+++ b/jsonnet/kube-prometheus/addons/external-metrics.libsonnet
@@ -2,9 +2,9 @@
 // For more details on usage visit https://github.com/DirectXMan12/k8s-prometheus-adapter#quick-links
 
 {
-  _config+:: {
-    prometheusAdapter+:: {
-      namespace: $._config.namespace,
+  values+:: {
+    prometheusAdapter+: {
+      namespace: $.values.common.namespace,
       // Rules for external-metrics
       config+:: {
         externalRules+: [
@@ -24,7 +24,7 @@
     },
   },
 
-  prometheusAdapter+:: {
+  prometheusAdapter+: {
     externalMetricsApiService: {
       apiVersion: 'apiregistration.k8s.io/v1',
       kind: 'APIService',
@@ -34,7 +34,7 @@
       spec: {
         service: {
           name: $.prometheusAdapter.service.metadata.name,
-          namespace: $._config.prometheusAdapter.namespace,
+          namespace: $.values.prometheusAdapter.namespace,
         },
         group: 'external.metrics.k8s.io',
         version: 'v1beta1',
@@ -70,7 +70,7 @@
       subjects: [{
         kind: 'ServiceAccount',
         name: $.prometheusAdapter.serviceAccount.metadata.name,
-        namespace: $._config.prometheusAdapter.namespace,
+        namespace: $.values.prometheusAdapter.namespace,
       }],
     },
     externalMetricsClusterRoleBindingHPA: {
diff --git a/jsonnet/kube-prometheus/kube-prometheus-insecure-kubelet.libsonnet b/jsonnet/kube-prometheus/addons/insecure-kubelet.libsonnet
similarity index 98%
rename from jsonnet/kube-prometheus/kube-prometheus-insecure-kubelet.libsonnet
rename to jsonnet/kube-prometheus/addons/insecure-kubelet.libsonnet
index 73d0b9d741e9413425d56ee643f754af6039279d..ab6f29434e1eb460b6d242519fc694f5e1f491fe 100644
--- a/jsonnet/kube-prometheus/kube-prometheus-insecure-kubelet.libsonnet
+++ b/jsonnet/kube-prometheus/addons/insecure-kubelet.libsonnet
@@ -1,5 +1,5 @@
 {
-  prometheus+:: {
+  prometheus+: {
     serviceMonitorKubelet+:
       {
         spec+: {
diff --git a/jsonnet/kube-prometheus/ksm-autoscaler/ksm-autoscaler.libsonnet b/jsonnet/kube-prometheus/addons/ksm-autoscaler.libsonnet
similarity index 69%
rename from jsonnet/kube-prometheus/ksm-autoscaler/ksm-autoscaler.libsonnet
rename to jsonnet/kube-prometheus/addons/ksm-autoscaler.libsonnet
index 88154ac1039d84d9f2e41cf1818c5a680702d2f3..fa2caf0e8e87cf78f34f79fef0d404602f59a741 100644
--- a/jsonnet/kube-prometheus/ksm-autoscaler/ksm-autoscaler.libsonnet
+++ b/jsonnet/kube-prometheus/addons/ksm-autoscaler.libsonnet
@@ -1,14 +1,15 @@
 {
-  _config+:: {
-    versions+:: { clusterVerticalAutoscaler: '0.8.1' },
-    imageRepos+:: { clusterVerticalAutoscaler: 'gcr.io/google_containers/cpvpa-amd64' },
-
-    kubeStateMetrics+:: {
+  values+:: {
+    clusterVerticalAutoscaler: {
+      version: '0.8.1',
+      image: 'gcr.io/google_containers/cpvpa-amd64:v0.8.1',
+      baseCPU: '1m',
       stepCPU: '1m',
+      baseMemory: '1Mi',
       stepMemory: '2Mi',
     },
   },
-  ksmAutoscaler+:: {
+  ksmAutoscaler+: {
     clusterRole: {
       apiVersion: 'rbac.authorization.k8s.io/v1',
       kind: 'ClusterRole',
@@ -29,7 +30,7 @@
         kind: 'ClusterRole',
         name: 'ksm-autoscaler',
       },
-      subjects: [{ kind: 'ServiceAccount', name: 'ksm-autoscaler', namespace: $._config.namespace }],
+      subjects: [{ kind: 'ServiceAccount', name: 'ksm-autoscaler', namespace: $.values.common.namespace }],
     },
 
     roleBinding: {
@@ -37,7 +38,7 @@
       kind: 'RoleBinding',
       metadata: {
         name: 'ksm-autoscaler',
-        namespace: $._config.namespace,
+        namespace: $.values.common.namespace,
       },
       roleRef: {
         apiGroup: 'rbac.authorization.k8s.io',
@@ -52,7 +53,7 @@
       kind: 'Role',
       metadata: {
         name: 'ksm-autoscaler',
-        namespace: $._config.namespace,
+        namespace: $.values.common.namespace,
       },
       rules: [
         {
@@ -75,7 +76,7 @@
       kind: 'ServiceAccount',
       metadata: {
         name: 'ksm-autoscaler',
-        namespace: $._config.namespace,
+        namespace: $.values.common.namespace,
       },
     },
 
@@ -83,14 +84,21 @@
       local podLabels = { app: 'ksm-autoscaler' };
       local c = {
         name: 'ksm-autoscaler',
-        image: $._config.imageRepos.clusterVerticalAutoscaler + ':v' + $._config.versions.clusterVerticalAutoscaler,
+        image: $.values.clusterVerticalAutoscaler.image,
         args: [
           '/cpvpa',
           '--target=deployment/kube-state-metrics',
-          '--namespace=' + $._config.namespace,
+          '--namespace=' + $.values.common.namespace,
           '--logtostderr=true',
           '--poll-period-seconds=10',
-          '--default-config={"kube-state-metrics":{"requests":{"cpu":{"base":"' + $._config.kubeStateMetrics.baseCPU + '","step":"' + $._config.kubeStateMetrics.stepCPU + '","nodesPerStep":1},"memory":{"base":"' + $._config.kubeStateMetrics.baseMemory + '","step":"' + $._config.kubeStateMetrics.stepMemory + '","nodesPerStep":1}},"limits":{"cpu":{"base":"' + $._config.kubeStateMetrics.baseCPU + '","step":"' + $._config.kubeStateMetrics.stepCPU + '","nodesPerStep":1},"memory":{"base":"' + $._config.kubeStateMetrics.baseMemory + '","step":"' + $._config.kubeStateMetrics.stepMemory + '","nodesPerStep":1}}}}',
+          '--default-config={"kube-state-metrics":{"requests":{"cpu":{"base":"' + $.values.clusterVerticalAutoscaler.baseCPU +
+          '","step":"' + $.values.clusterVerticalAutoscaler.stepCPU +
+          '","nodesPerStep":1},"memory":{"base":"' + $.values.clusterVerticalAutoscaler.baseMemory +
+          '","step":"' + $.values.clusterVerticalAutoscaler.stepMemory +
+          '","nodesPerStep":1}},"limits":{"cpu":{"base":"' + $.values.clusterVerticalAutoscaler.baseCPU +
+          '","step":"' + $.values.clusterVerticalAutoscaler.stepCPU +
+          '","nodesPerStep":1},"memory":{"base":"' + $.values.clusterVerticalAutoscaler.baseMemory +
+          '","step":"' + $.values.clusterVerticalAutoscaler.stepMemory + '","nodesPerStep":1}}}}',
         ],
         resources: {
           requests: { cpu: '20m', memory: '10Mi' },
@@ -102,7 +110,7 @@
         kind: 'Deployment',
         metadata: {
           name: 'ksm-autoscaler',
-          namespace: $._config.namespace,
+          namespace: $.values.common.namespace,
           labels: podLabels,
         },
         spec: {
diff --git a/jsonnet/kube-prometheus/kube-prometheus-managed-cluster.libsonnet b/jsonnet/kube-prometheus/addons/managed-cluster.libsonnet
similarity index 91%
rename from jsonnet/kube-prometheus/kube-prometheus-managed-cluster.libsonnet
rename to jsonnet/kube-prometheus/addons/managed-cluster.libsonnet
index 9b4e1a8cdd0e764d1c5fb7029fbdead178efe374..5b37c56e569d2f34f914daf41912d06eb14f672c 100644
--- a/jsonnet/kube-prometheus/kube-prometheus-managed-cluster.libsonnet
+++ b/jsonnet/kube-prometheus/addons/managed-cluster.libsonnet
@@ -1,8 +1,8 @@
 // On managed Kubernetes clusters some of the control plane components are not exposed to customers.
-// Disable scrape jobs, service monitors, and alert groups for these components by overwriting 'kube-prometheus.libsonnet' defaults
+// Disable scrape jobs, service monitors, and alert groups for these components by overwriting 'main.libsonnet' defaults
 
 {
-  _config+:: {
+  values+:: {
     // This snippet walks the original object (super.jobs, set as temp var j) and creates a replacement jobs object
     //     excluding any members of the set specified (eg: controller and scheduler).
     local j = super.jobs,
@@ -13,7 +13,7 @@
     },
 
     // Skip alerting rules too
-    prometheus+:: {
+    prometheus+: {
       rules+:: {
         local g = super.groups,
         groups: [
diff --git a/jsonnet/kube-prometheus/kube-prometheus-node-ports.libsonnet b/jsonnet/kube-prometheus/addons/node-ports.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/kube-prometheus-node-ports.libsonnet
rename to jsonnet/kube-prometheus/addons/node-ports.libsonnet
diff --git a/jsonnet/kube-prometheus/kube-prometheus-static-etcd.libsonnet b/jsonnet/kube-prometheus/addons/static-etcd.libsonnet
similarity index 83%
rename from jsonnet/kube-prometheus/kube-prometheus-static-etcd.libsonnet
rename to jsonnet/kube-prometheus/addons/static-etcd.libsonnet
index e4c3a14d08b0ef21535432921bb032daa2f6cb9b..d49bc63392d2c440185ff6a94937b649fb99012b 100644
--- a/jsonnet/kube-prometheus/kube-prometheus-static-etcd.libsonnet
+++ b/jsonnet/kube-prometheus/addons/static-etcd.libsonnet
@@ -1,5 +1,5 @@
 (import 'github.com/etcd-io/etcd/Documentation/etcd-mixin/mixin.libsonnet') + {
-  _config+:: {
+  values+:: {
     etcd: {
       ips: [],
       clientCA: null,
@@ -9,7 +9,7 @@
       insecureSkipVerify: null,
     },
   },
-  prometheus+:: {
+  prometheus+: {
     serviceEtcd: {
       apiVersion: 'v1',
       kind: 'Service',
@@ -36,7 +36,7 @@
       subsets: [{
         addresses: [
           { ip: etcdIP }
-          for etcdIP in $._config.etcd.ips
+          for etcdIP in $.values.etcd.ips
         ],
         ports: [
           { name: 'metrics', port: 2379, protocol: 'TCP' },
@@ -65,8 +65,8 @@
               caFile: '/etc/prometheus/secrets/kube-etcd-client-certs/etcd-client-ca.crt',
               keyFile: '/etc/prometheus/secrets/kube-etcd-client-certs/etcd-client.key',
               certFile: '/etc/prometheus/secrets/kube-etcd-client-certs/etcd-client.crt',
-              [if $._config.etcd.serverName != null then 'serverName']: $._config.etcd.serverName,
-              [if $._config.etcd.insecureSkipVerify != null then 'insecureSkipVerify']: $._config.etcd.insecureSkipVerify,
+              [if $.values.etcd.serverName != null then 'serverName']: $.values.etcd.serverName,
+              [if $.values.etcd.insecureSkipVerify != null then 'insecureSkipVerify']: $.values.etcd.insecureSkipVerify,
             },
           },
         ],
@@ -84,12 +84,12 @@
       type: 'Opaque',
       metadata: {
         name: 'kube-etcd-client-certs',
-        namespace: $._config.namespace,
+        namespace: $.values.common.namespace,
       },
       data: {
-        'etcd-client-ca.crt': std.base64($._config.etcd.clientCA),
-        'etcd-client.key': std.base64($._config.etcd.clientKey),
-        'etcd-client.crt': std.base64($._config.etcd.clientCert),
+        'etcd-client-ca.crt': std.base64($.values.etcd.clientCA),
+        'etcd-client.key': std.base64($.values.etcd.clientKey),
+        'etcd-client.crt': std.base64($.values.etcd.clientCert),
       },
     },
     prometheus+: {
diff --git a/jsonnet/kube-prometheus/addons/strip-limits.libsonnet b/jsonnet/kube-prometheus/addons/strip-limits.libsonnet
new file mode 100644
index 0000000000000000000000000000000000000000..83c5f77b8ccc62169d63213ddaeca1f5456ac382
--- /dev/null
+++ b/jsonnet/kube-prometheus/addons/strip-limits.libsonnet
@@ -0,0 +1,48 @@
+// Strips spec.containers[].limits for certain containers
+// https://github.com/prometheus-operator/kube-prometheus/issues/72
+
+{
+  local noLimit(c) =
+    //if std.objectHas(c, 'resources') && c.name != 'kube-state-metrics'
+    if c.name != 'kube-state-metrics'
+    then c { resources+: { limits: {} } }
+    else c,
+
+  nodeExporter+: {
+    daemonset+: {
+      spec+: {
+        template+: {
+          spec+: {
+            containers: std.map(noLimit, super.containers),
+          },
+        },
+      },
+    },
+  },
+  kubeStateMetrics+: {
+    deployment+: {
+      spec+: {
+        template+: {
+          spec+: {
+            containers: std.map(noLimit, super.containers),
+          },
+        },
+      },
+    },
+  },
+  prometheusOperator+: {
+    deployment+: {
+      spec+: {
+        template+: {
+          spec+: {
+            local addArgs(c) =
+              if c.name == 'prometheus-operator'
+              then c { args+: ['--config-reloader-cpu=0'] }
+              else c,
+            containers: std.map(addArgs, super.containers),
+          },
+        },
+      },
+    },
+  },
+}
diff --git a/jsonnet/kube-prometheus/kube-prometheus-thanos-sidecar.libsonnet b/jsonnet/kube-prometheus/addons/thanos-sidecar.libsonnet
similarity index 76%
rename from jsonnet/kube-prometheus/kube-prometheus-thanos-sidecar.libsonnet
rename to jsonnet/kube-prometheus/addons/thanos-sidecar.libsonnet
index 01620d4a837f9a23851331e828724a32049fdbd8..af6474d2dacb725dd75dfbe63a08c7ee6dd10567 100644
--- a/jsonnet/kube-prometheus/kube-prometheus-thanos-sidecar.libsonnet
+++ b/jsonnet/kube-prometheus/addons/thanos-sidecar.libsonnet
@@ -1,16 +1,16 @@
 (import 'github.com/thanos-io/thanos/mixin/alerts/sidecar.libsonnet') +
 {
-  _config+:: {
-    versions+:: { thanos: 'v0.14.0' },
-    imageRepos+:: { thanos: 'quay.io/thanos/thanos' },
+  values+:: {
     thanos+:: {
+      version: '0.14.0',
+      image: 'quay.io/thanos/thanos:v0.14.0',
       objectStorageConfig: {
         key: 'thanos.yaml',  // How the file inside the secret is called
         name: 'thanos-objectstorage',  // This is the name of your Kubernetes secret with the config
       },
     },
   },
-  prometheus+:: {
+  prometheus+: {
     local p = self,
 
     // Add the grpc port to the Prometheus service to be able to query it with the Thanos Querier
@@ -26,9 +26,9 @@
       apiVersion: 'v1',
       kind: 'Service',
       metadata: {
-        name: 'prometheus-' + p.name + '-thanos-sidecar',
-        namespace: p.namespace,
-        labels: { prometheus: p.name, app: 'thanos-sidecar' },
+        name: 'prometheus-' + p.config.name + '-thanos-sidecar',
+        namespace: p.config.namespace,
+        labels: { prometheus: p.config.name, app: 'thanos-sidecar' },
       },
       spec: {
         ports: [
@@ -42,9 +42,9 @@
     prometheus+: {
       spec+: {
         thanos+: {
-          version: $._config.versions.thanos,
-          image: $._config.imageRepos.thanos + ':' + $._config.versions.thanos,
-          objectStorageConfig: $._config.thanos.objectStorageConfig,
+          version: $.values.thanos.version,
+          image: $.values.thanos.image,
+          objectStorageConfig: $.values.thanos.objectStorageConfig,
         },
       },
     },
@@ -54,7 +54,7 @@
         kind: 'ServiceMonitor',
         metadata: {
           name: 'thanos-sidecar',
-          namespace: p.namespace,
+          namespace: p.config.namespace,
           labels: {
             'app.kubernetes.io/name': 'prometheus',
           },
@@ -64,7 +64,7 @@
           jobLabel: 'app',
           selector: {
             matchLabels: {
-              prometheus: p.name,
+              prometheus: p.config.name,
               app: 'thanos-sidecar',
             },
           },
diff --git a/jsonnet/kube-prometheus/addons/weave-net/alerts.libsonnet b/jsonnet/kube-prometheus/addons/weave-net/alerts.libsonnet
new file mode 100644
index 0000000000000000000000000000000000000000..c0ca940a9ca7260f99c0e2cacbbdec3ce1d5b71a
--- /dev/null
+++ b/jsonnet/kube-prometheus/addons/weave-net/alerts.libsonnet
@@ -0,0 +1,134 @@
+[
+  {
+    alert: 'WeaveNetIPAMSplitBrain',
+    expr: 'max(weave_ipam_unreachable_percentage) - min(weave_ipam_unreachable_percentage) > 0',
+    'for': '3m',
+    labels: {
+      severity: 'critical',
+    },
+    annotations: {
+      summary: 'Percentage of all IP addresses owned by unreachable peers is not same for every node.',
+      description: 'actionable: Weave Net network has a split brain problem. Please find the problem and fix it.',
+    },
+  },
+  {
+    alert: 'WeaveNetIPAMUnreachable',
+    expr: 'weave_ipam_unreachable_percentage > 25',
+    'for': '10m',
+    labels: {
+      severity: 'critical',
+    },
+    annotations: {
+      summary: 'Percentage of all IP addresses owned by unreachable peers is above threshold.',
+      description: 'actionable: Please find the problem and fix it.',
+    },
+  },
+  {
+    alert: 'WeaveNetIPAMPendingAllocates',
+    expr: 'sum(weave_ipam_pending_allocates) > 0',
+    'for': '3m',
+    labels: {
+      severity: 'critical',
+    },
+    annotations: {
+      summary: 'Number of pending allocates is above the threshold.',
+      description: 'actionable: Please find the problem and fix it.',
+    },
+  },
+  {
+    alert: 'WeaveNetIPAMPendingClaims',
+    expr: 'sum(weave_ipam_pending_claims) > 0',
+    'for': '3m',
+    labels: {
+      severity: 'critical',
+    },
+    annotations: {
+      summary: 'Number of pending claims is above the threshold.',
+      description: 'actionable: Please find the problem and fix it.',
+    },
+  },
+  {
+    alert: 'WeaveNetFastDPFlowsLow',
+    expr: 'sum(weave_flows) < 15000',
+    'for': '3m',
+    labels: {
+      severity: 'critical',
+    },
+    annotations: {
+      summary: 'Number of FastDP flows is below the threshold.',
+      description: 'actionable: Please find the reason for FastDP flows to go below the threshold and fix it.',
+    },
+  },
+  {
+    alert: 'WeaveNetFastDPFlowsOff',
+    expr: 'sum(weave_flows == bool 0) > 0',
+    'for': '3m',
+    labels: {
+      severity: 'critical',
+    },
+    annotations: {
+      summary: 'FastDP flows is zero.',
+      description: 'actionable: Please find the reason for FastDP flows to be off and fix it.',
+    },
+  },
+  {
+    alert: 'WeaveNetHighConnectionTerminationRate',
+    expr: 'rate(weave_connection_terminations_total[5m]) > 0.1',
+    'for': '5m',
+    labels: {
+      severity: 'critical',
+    },
+    annotations: {
+      summary: 'A lot of connections are getting terminated.',
+      description: 'actionable: Please find the reason for the high connection termination rate and fix it.',
+    },
+  },
+  {
+    alert: 'WeaveNetConnectionsConnecting',
+    expr: 'sum(weave_connections{state="connecting"}) > 0',
+    'for': '3m',
+    labels: {
+      severity: 'critical',
+    },
+    annotations: {
+      summary: 'A lot of connections are in connecting state.',
+      description: 'actionable: Please find the reason for this and fix it.',
+    },
+  },
+  {
+    alert: 'WeaveNetConnectionsRetying',
+    expr: 'sum(weave_connections{state="retrying"}) > 0',
+    'for': '3m',
+    labels: {
+      severity: 'critical',
+    },
+    annotations: {
+      summary: 'A lot of connections are in retrying state.',
+      description: 'actionable: Please find the reason for this and fix it.',
+    },
+  },
+  {
+    alert: 'WeaveNetConnectionsPending',
+    expr: 'sum(weave_connections{state="pending"}) > 0',
+    'for': '3m',
+    labels: {
+      severity: 'critical',
+    },
+    annotations: {
+      summary: 'A lot of connections are in pending state.',
+      description: 'actionable: Please find the reason for this and fix it.',
+    },
+  },
+  {
+    alert: 'WeaveNetConnectionsFailed',
+    expr: 'sum(weave_connections{state="failed"}) > 0',
+    'for': '3m',
+    labels: {
+      severity: 'critical',
+    },
+    annotations: {
+      summary: 'A lot of connections are in failed state.',
+      description: 'actionable: Please find the reason and fix it.',
+    },
+  },
+]
diff --git a/jsonnet/kube-prometheus/grafana-weave-net-cluster.json b/jsonnet/kube-prometheus/addons/weave-net/grafana-weave-net-cluster.json
similarity index 100%
rename from jsonnet/kube-prometheus/grafana-weave-net-cluster.json
rename to jsonnet/kube-prometheus/addons/weave-net/grafana-weave-net-cluster.json
diff --git a/jsonnet/kube-prometheus/grafana-weave-net.json b/jsonnet/kube-prometheus/addons/weave-net/grafana-weave-net.json
similarity index 100%
rename from jsonnet/kube-prometheus/grafana-weave-net.json
rename to jsonnet/kube-prometheus/addons/weave-net/grafana-weave-net.json
diff --git a/jsonnet/kube-prometheus/addons/weave-net/weave-net.libsonnet b/jsonnet/kube-prometheus/addons/weave-net/weave-net.libsonnet
new file mode 100644
index 0000000000000000000000000000000000000000..71596f4568aac7fcd46869dd3f84c8406ef9fd2d
--- /dev/null
+++ b/jsonnet/kube-prometheus/addons/weave-net/weave-net.libsonnet
@@ -0,0 +1,73 @@
+{
+  prometheus+: {
+    local p = self,
+    serviceWeaveNet: {
+      apiVersion: 'v1',
+      kind: 'Service',
+      metadata: {
+        name: 'weave-net',
+        namespace: 'kube-system',
+        labels: { 'app.kubernetes.io/name': 'weave-net' },
+      },
+      spec: {
+        ports: [
+          { name: 'weave-net-metrics', targetPort: 6782, port: 6782 },
+        ],
+        selector: { name: 'weave-net' },
+        clusterIP: 'None',
+      },
+    },
+    serviceMonitorWeaveNet: {
+      apiVersion: 'monitoring.coreos.com/v1',
+      kind: 'ServiceMonitor',
+      metadata: {
+        name: 'weave-net',
+        labels: {
+          'app.kubernetes.io/name': 'weave-net',
+        },
+        namespace: 'monitoring',
+      },
+      spec: {
+        jobLabel: 'app.kubernetes.io/name',
+        endpoints: [
+          {
+            port: 'weave-net-metrics',
+            path: '/metrics',
+            interval: '15s',
+          },
+        ],
+        namespaceSelector: {
+          matchNames: [
+            'kube-system',
+          ],
+        },
+        selector: {
+          matchLabels: {
+            'app.kubernetes.io/name': 'weave-net',
+          },
+        },
+      },
+    },
+    prometheusRuleWeaveNet: {
+      apiVersion: 'monitoring.coreos.com/v1',
+      kind: 'PrometheusRule',
+      metadata: {
+        labels: p.config.mixin.ruleLabels,
+        name: 'weave-net-rules',
+        namespace: p.config.namespace,
+      },
+      spec: {
+        groups: [{
+          name: 'weave-net',
+          rules: (import './alerts.libsonnet'),
+        }],
+      },
+    },
+    mixin+:: {
+      grafanaDashboards+:: {
+        'weave-net.json': (import './grafana-weave-net.json'),
+        'weave-net-cluster.json': (import './grafana-weave-net-cluster.json'),
+      },
+    },
+  },
+}
diff --git a/jsonnet/kube-prometheus/alertmanager/alertmanager.libsonnet b/jsonnet/kube-prometheus/components/alertmanager.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/alertmanager/alertmanager.libsonnet
rename to jsonnet/kube-prometheus/components/alertmanager.libsonnet
diff --git a/jsonnet/kube-prometheus/blackbox-exporter/blackbox-exporter.libsonnet b/jsonnet/kube-prometheus/components/blackbox-exporter.libsonnet
similarity index 99%
rename from jsonnet/kube-prometheus/blackbox-exporter/blackbox-exporter.libsonnet
rename to jsonnet/kube-prometheus/components/blackbox-exporter.libsonnet
index ce421209e7235ec12f158de362d5e435325d37c1..bbe03ed694a8fa9f7d41a3709a6e4fe673d3a768 100644
--- a/jsonnet/kube-prometheus/blackbox-exporter/blackbox-exporter.libsonnet
+++ b/jsonnet/kube-prometheus/components/blackbox-exporter.libsonnet
@@ -1,4 +1,4 @@
-local krp = import '../kube-rbac-proxy/container.libsonnet';
+local krp = import './kube-rbac-proxy.libsonnet';
 
 local defaults = {
   local defaults = self,
diff --git a/jsonnet/kube-prometheus/grafana/grafana.libsonnet b/jsonnet/kube-prometheus/components/grafana.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/grafana/grafana.libsonnet
rename to jsonnet/kube-prometheus/components/grafana.libsonnet
diff --git a/jsonnet/kube-prometheus/kube-rbac-proxy/container.libsonnet b/jsonnet/kube-prometheus/components/kube-rbac-proxy.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/kube-rbac-proxy/container.libsonnet
rename to jsonnet/kube-prometheus/components/kube-rbac-proxy.libsonnet
diff --git a/jsonnet/kube-prometheus/kube-state-metrics/kube-state-metrics.libsonnet b/jsonnet/kube-prometheus/components/kube-state-metrics.libsonnet
similarity index 98%
rename from jsonnet/kube-prometheus/kube-state-metrics/kube-state-metrics.libsonnet
rename to jsonnet/kube-prometheus/components/kube-state-metrics.libsonnet
index fdfe3bd59eadf3dec9f05a47f755fa2aa4b08f74..fa1bfd596c4ce492acbb7346e823ce27d8fe760b 100644
--- a/jsonnet/kube-prometheus/kube-state-metrics/kube-state-metrics.libsonnet
+++ b/jsonnet/kube-prometheus/components/kube-state-metrics.libsonnet
@@ -1,4 +1,4 @@
-local krp = (import '../kube-rbac-proxy/container.libsonnet');
+local krp = import './kube-rbac-proxy.libsonnet';
 
 local defaults = {
   local defaults = self,
diff --git a/jsonnet/kube-prometheus/mixin/alerts/alerts.libsonnet b/jsonnet/kube-prometheus/components/mixin/alerts/alerts.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/mixin/alerts/alerts.libsonnet
rename to jsonnet/kube-prometheus/components/mixin/alerts/alerts.libsonnet
diff --git a/jsonnet/kube-prometheus/mixin/alerts/general.libsonnet b/jsonnet/kube-prometheus/components/mixin/alerts/general.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/mixin/alerts/general.libsonnet
rename to jsonnet/kube-prometheus/components/mixin/alerts/general.libsonnet
diff --git a/jsonnet/kube-prometheus/mixin/alerts/node.libsonnet b/jsonnet/kube-prometheus/components/mixin/alerts/node.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/mixin/alerts/node.libsonnet
rename to jsonnet/kube-prometheus/components/mixin/alerts/node.libsonnet
diff --git a/jsonnet/kube-prometheus/mixin/alerts/tests.yaml b/jsonnet/kube-prometheus/components/mixin/alerts/tests.yaml
similarity index 100%
rename from jsonnet/kube-prometheus/mixin/alerts/tests.yaml
rename to jsonnet/kube-prometheus/components/mixin/alerts/tests.yaml
diff --git a/jsonnet/kube-prometheus/mixin/custom.libsonnet b/jsonnet/kube-prometheus/components/mixin/custom.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/mixin/custom.libsonnet
rename to jsonnet/kube-prometheus/components/mixin/custom.libsonnet
diff --git a/jsonnet/kube-prometheus/mixin/kubernetes.libsonnet b/jsonnet/kube-prometheus/components/mixin/kubernetes.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/mixin/kubernetes.libsonnet
rename to jsonnet/kube-prometheus/components/mixin/kubernetes.libsonnet
diff --git a/jsonnet/kube-prometheus/mixin/rules/general.libsonnet b/jsonnet/kube-prometheus/components/mixin/rules/general.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/mixin/rules/general.libsonnet
rename to jsonnet/kube-prometheus/components/mixin/rules/general.libsonnet
diff --git a/jsonnet/kube-prometheus/mixin/rules/node-rules.libsonnet b/jsonnet/kube-prometheus/components/mixin/rules/node-rules.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/mixin/rules/node-rules.libsonnet
rename to jsonnet/kube-prometheus/components/mixin/rules/node-rules.libsonnet
diff --git a/jsonnet/kube-prometheus/mixin/rules/rules.libsonnet b/jsonnet/kube-prometheus/components/mixin/rules/rules.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/mixin/rules/rules.libsonnet
rename to jsonnet/kube-prometheus/components/mixin/rules/rules.libsonnet
diff --git a/jsonnet/kube-prometheus/node-exporter/node-exporter.libsonnet b/jsonnet/kube-prometheus/components/node-exporter.libsonnet
similarity index 99%
rename from jsonnet/kube-prometheus/node-exporter/node-exporter.libsonnet
rename to jsonnet/kube-prometheus/components/node-exporter.libsonnet
index c5b82498f45caec0a65c0a1daa05e6f885381097..bd4fbfe7ab3d2d98b598de0f80528c7469d1ceba 100644
--- a/jsonnet/kube-prometheus/node-exporter/node-exporter.libsonnet
+++ b/jsonnet/kube-prometheus/components/node-exporter.libsonnet
@@ -1,4 +1,4 @@
-local krp = (import '../kube-rbac-proxy/container.libsonnet');
+local krp = import './kube-rbac-proxy.libsonnet';
 
 local defaults = {
   local defaults = self,
diff --git a/jsonnet/kube-prometheus/prometheus-adapter/prometheus-adapter.libsonnet b/jsonnet/kube-prometheus/components/prometheus-adapter.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/prometheus-adapter/prometheus-adapter.libsonnet
rename to jsonnet/kube-prometheus/components/prometheus-adapter.libsonnet
diff --git a/jsonnet/kube-prometheus/prometheus-operator/prometheus-operator.libsonnet b/jsonnet/kube-prometheus/components/prometheus-operator.libsonnet
similarity index 98%
rename from jsonnet/kube-prometheus/prometheus-operator/prometheus-operator.libsonnet
rename to jsonnet/kube-prometheus/components/prometheus-operator.libsonnet
index 8114f91cc24968382316d4d0baa9f349d14c8bdb..96f263d9f70766d023087ab633062aac119b4564 100644
--- a/jsonnet/kube-prometheus/prometheus-operator/prometheus-operator.libsonnet
+++ b/jsonnet/kube-prometheus/components/prometheus-operator.libsonnet
@@ -1,4 +1,4 @@
-local krp = (import '../kube-rbac-proxy/container.libsonnet');
+local krp = import './kube-rbac-proxy.libsonnet';
 local prometheusOperator = import 'github.com/prometheus-operator/prometheus-operator/jsonnet/prometheus-operator/prometheus-operator.libsonnet';
 
 local defaults = {
diff --git a/jsonnet/kube-prometheus/prometheus/prometheus.libsonnet b/jsonnet/kube-prometheus/components/prometheus.libsonnet
similarity index 99%
rename from jsonnet/kube-prometheus/prometheus/prometheus.libsonnet
rename to jsonnet/kube-prometheus/components/prometheus.libsonnet
index 76a251ff3ab4f45cb44799f78f5b33bc6286a8b0..e93f85376e61f579e12c9c36b2dc5a4fe50bb1e2 100644
--- a/jsonnet/kube-prometheus/prometheus/prometheus.libsonnet
+++ b/jsonnet/kube-prometheus/components/prometheus.libsonnet
@@ -1,4 +1,4 @@
-local relabelings = import 'kube-prometheus/dropping-deprecated-metrics-relabelings.libsonnet';
+local relabelings = import '../addons/dropping-deprecated-metrics-relabelings.libsonnet';
 
 local defaults = {
   local defaults = self,
diff --git a/jsonnet/kube-prometheus/kube-prometheus-ksonnet.libsonnet b/jsonnet/kube-prometheus/kube-prometheus-ksonnet.libsonnet
deleted file mode 100644
index ad13373fda32dadc392e6f88df587ccc74de2e1c..0000000000000000000000000000000000000000
--- a/jsonnet/kube-prometheus/kube-prometheus-ksonnet.libsonnet
+++ /dev/null
@@ -1,8 +0,0 @@
-local kp = (import './kube-prometheus/kube-prometheus.libsonnet');
-
-{ ['0prometheus-operator-' + name]: kp.prometheusOperator[name] for name in std.objectFields(kp.prometheusOperator) } +
-{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
-{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
-{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
-{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
-{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
diff --git a/jsonnet/kube-prometheus/kube-prometheus-strip-limits.libsonnet b/jsonnet/kube-prometheus/kube-prometheus-strip-limits.libsonnet
deleted file mode 100644
index fbd40200a47c5592783cc75d4eb2a94dbe63b68b..0000000000000000000000000000000000000000
--- a/jsonnet/kube-prometheus/kube-prometheus-strip-limits.libsonnet
+++ /dev/null
@@ -1,35 +0,0 @@
-// Strips spec.containers[].limits for certain containers
-// https://github.com/prometheus-operator/kube-prometheus/issues/72
-{
-  _config+:: {
-    resources+:: {
-      'addon-resizer'+: {
-        limits: {},
-      },
-      'kube-rbac-proxy'+: {
-        limits: {},
-      },
-      'kube-state-metrics'+: {
-        limits: {},
-      },
-      'node-exporter'+: {
-        limits: {},
-      },
-    },
-  },
-  prometheusOperator+: {
-    deployment+: {
-      spec+: {
-        template+: {
-          spec+: {
-            local addArgs(c) =
-              if c.name == 'prometheus-operator'
-              then c { args+: ['--config-reloader-cpu=0'] }
-              else c,
-            containers: std.map(addArgs, super.containers),
-          },
-        },
-      },
-    },
-  },
-}
diff --git a/jsonnet/kube-prometheus/kube-prometheus-weave-net.libsonnet b/jsonnet/kube-prometheus/kube-prometheus-weave-net.libsonnet
deleted file mode 100644
index 0755e60c83143931fb6861b34db7ca87e25ea68f..0000000000000000000000000000000000000000
--- a/jsonnet/kube-prometheus/kube-prometheus-weave-net.libsonnet
+++ /dev/null
@@ -1,196 +0,0 @@
-{
-  prometheus+: {
-    serviceWeaveNet: {
-      apiVersion: 'v1',
-      kind: 'Service',
-      metadata: {
-        name: 'weave-net',
-        namespace: 'kube-system',
-        labels: { 'app.kubernetes.io/name': 'weave-net' },
-      },
-      spec: {
-        ports: [
-          { name: 'weave-net-metrics', targetPort: 6782, port: 6782 },
-        ],
-        selector: { name: 'weave-net' },
-        clusterIP: 'None',
-      },
-    },
-    serviceMonitorWeaveNet: {
-      apiVersion: 'monitoring.coreos.com/v1',
-      kind: 'ServiceMonitor',
-      metadata: {
-        name: 'weave-net',
-        labels: {
-          'app.kubernetes.io/name': 'weave-net',
-        },
-        namespace: 'monitoring',
-      },
-      spec: {
-        jobLabel: 'app.kubernetes.io/name',
-        endpoints: [
-          {
-            port: 'weave-net-metrics',
-            path: '/metrics',
-            interval: '15s',
-          },
-        ],
-        namespaceSelector: {
-          matchNames: [
-            'kube-system',
-          ],
-        },
-        selector: {
-          matchLabels: {
-            'app.kubernetes.io/name': 'weave-net',
-          },
-        },
-      },
-    },
-  },
-  prometheusRules+: {
-    groups+: [
-      {
-        name: 'weave-net',
-        rules: [
-          {
-            alert: 'WeaveNetIPAMSplitBrain',
-            expr: 'max(weave_ipam_unreachable_percentage) - min(weave_ipam_unreachable_percentage) > 0',
-            'for': '3m',
-            labels: {
-              severity: 'critical',
-            },
-            annotations: {
-              summary: 'Percentage of all IP addresses owned by unreachable peers is not same for every node.',
-              description: 'actionable: Weave Net network has a split brain problem. Please find the problem and fix it.',
-            },
-          },
-          {
-            alert: 'WeaveNetIPAMUnreachable',
-            expr: 'weave_ipam_unreachable_percentage > 25',
-            'for': '10m',
-            labels: {
-              severity: 'critical',
-            },
-            annotations: {
-              summary: 'Percentage of all IP addresses owned by unreachable peers is above threshold.',
-              description: 'actionable: Please find the problem and fix it.',
-            },
-          },
-          {
-            alert: 'WeaveNetIPAMPendingAllocates',
-            expr: 'sum(weave_ipam_pending_allocates) > 0',
-            'for': '3m',
-            labels: {
-              severity: 'critical',
-            },
-            annotations: {
-              summary: 'Number of pending allocates is above the threshold.',
-              description: 'actionable: Please find the problem and fix it.',
-            },
-          },
-          {
-            alert: 'WeaveNetIPAMPendingClaims',
-            expr: 'sum(weave_ipam_pending_claims) > 0',
-            'for': '3m',
-            labels: {
-              severity: 'critical',
-            },
-            annotations: {
-              summary: 'Number of pending claims is above the threshold.',
-              description: 'actionable: Please find the problem and fix it.',
-            },
-          },
-          {
-            alert: 'WeaveNetFastDPFlowsLow',
-            expr: 'sum(weave_flows) < 15000',
-            'for': '3m',
-            labels: {
-              severity: 'critical',
-            },
-            annotations: {
-              summary: 'Number of FastDP flows is below the threshold.',
-              description: 'actionable: Please find the reason for FastDP flows to go below the threshold and fix it.',
-            },
-          },
-          {
-            alert: 'WeaveNetFastDPFlowsOff',
-            expr: 'sum(weave_flows == bool 0) > 0',
-            'for': '3m',
-            labels: {
-              severity: 'critical',
-            },
-            annotations: {
-              summary: 'FastDP flows is zero.',
-              description: 'actionable: Please find the reason for FastDP flows to be off and fix it.',
-            },
-          },
-          {
-            alert: 'WeaveNetHighConnectionTerminationRate',
-            expr: 'rate(weave_connection_terminations_total[5m]) > 0.1',
-            'for': '5m',
-            labels: {
-              severity: 'critical',
-            },
-            annotations: {
-              summary: 'A lot of connections are getting terminated.',
-              description: 'actionable: Please find the reason for the high connection termination rate and fix it.',
-            },
-          },
-          {
-            alert: 'WeaveNetConnectionsConnecting',
-            expr: 'sum(weave_connections{state="connecting"}) > 0',
-            'for': '3m',
-            labels: {
-              severity: 'critical',
-            },
-            annotations: {
-              summary: 'A lot of connections are in connecting state.',
-              description: 'actionable: Please find the reason for this and fix it.',
-            },
-          },
-          {
-            alert: 'WeaveNetConnectionsRetying',
-            expr: 'sum(weave_connections{state="retrying"}) > 0',
-            'for': '3m',
-            labels: {
-              severity: 'critical',
-            },
-            annotations: {
-              summary: 'A lot of connections are in retrying state.',
-              description: 'actionable: Please find the reason for this and fix it.',
-            },
-          },
-          {
-            alert: 'WeaveNetConnectionsPending',
-            expr: 'sum(weave_connections{state="pending"}) > 0',
-            'for': '3m',
-            labels: {
-              severity: 'critical',
-            },
-            annotations: {
-              summary: 'A lot of connections are in pending state.',
-              description: 'actionable: Please find the reason for this and fix it.',
-            },
-          },
-          {
-            alert: 'WeaveNetConnectionsFailed',
-            expr: 'sum(weave_connections{state="failed"}) > 0',
-            'for': '3m',
-            labels: {
-              severity: 'critical',
-            },
-            annotations: {
-              summary: 'A lot of connections are in failed state.',
-              description: 'actionable: Please find the reason and fix it.',
-            },
-          },
-        ],
-      },
-    ],
-  },
-  grafanaDashboards+:: {
-    'weave-net.json': (import './grafana-weave-net.json'),
-    'weave-net-cluster.json': (import './grafana-weave-net-cluster.json'),
-  },
-}
diff --git a/jsonnet/kube-prometheus/lib/image.libsonnet b/jsonnet/kube-prometheus/lib/image.libsonnet
deleted file mode 100644
index 723d1b38981f1d4d3c6cb40ae3d690e63e7f9cae..0000000000000000000000000000000000000000
--- a/jsonnet/kube-prometheus/lib/image.libsonnet
+++ /dev/null
@@ -1,21 +0,0 @@
-// imageName extracts the image name from a fully qualified image string. eg.
-// quay.io/coreos/addon-resizer -> addon-resizer
-// grafana/grafana -> grafana
-local imageName(image) =
-  local parts = std.split(image, '/');
-  local len = std.length(parts);
-  if len == 3 then
-    // registry.com/org/image
-    parts[2]
-  else if len == 2 then
-    // org/image
-    parts[1]
-  else if len == 1 then
-    // image, ie. busybox
-    parts[0]
-  else
-    error 'unknown image format: ' + image;
-
-{
-  imageName:: imageName,
-}
diff --git a/jsonnet/kube-prometheus/lib/lib.libsonnet b/jsonnet/kube-prometheus/lib/lib.libsonnet
deleted file mode 100644
index c30f976f15a4367a4361c72306aa579e5580f6fe..0000000000000000000000000000000000000000
--- a/jsonnet/kube-prometheus/lib/lib.libsonnet
+++ /dev/null
@@ -1 +0,0 @@
-(import 'image.libsonnet')
diff --git a/jsonnet/kube-prometheus/kube-prometheus.libsonnet b/jsonnet/kube-prometheus/main.libsonnet
similarity index 82%
rename from jsonnet/kube-prometheus/kube-prometheus.libsonnet
rename to jsonnet/kube-prometheus/main.libsonnet
index d5346317aa0173fda285408bea8a21cf67e1aefe..15f88b7d7f8487959c579586ebf5632f8c3ee688 100644
--- a/jsonnet/kube-prometheus/kube-prometheus.libsonnet
+++ b/jsonnet/kube-prometheus/main.libsonnet
@@ -1,13 +1,13 @@
-local alertmanager = import './alertmanager/alertmanager.libsonnet';
-local blackboxExporter = import './blackbox-exporter/blackbox-exporter.libsonnet';
-local grafana = import './grafana/grafana.libsonnet';
-local kubeStateMetrics = import './kube-state-metrics/kube-state-metrics.libsonnet';
-local customMixin = import './mixin/custom.libsonnet';
-local kubernetesMixin = import './mixin/kubernetes.libsonnet';
-local nodeExporter = import './node-exporter/node-exporter.libsonnet';
-local prometheusAdapter = import './prometheus-adapter/prometheus-adapter.libsonnet';
-local prometheusOperator = import './prometheus-operator/prometheus-operator.libsonnet';
-local prometheus = import './prometheus/prometheus.libsonnet';
+local alertmanager = import './components/alertmanager.libsonnet';
+local blackboxExporter = import './components/blackbox-exporter.libsonnet';
+local grafana = import './components/grafana.libsonnet';
+local kubeStateMetrics = import './components/kube-state-metrics.libsonnet';
+local customMixin = import './components/mixin/custom.libsonnet';
+local kubernetesMixin = import './components/mixin/kubernetes.libsonnet';
+local nodeExporter = import './components/node-exporter.libsonnet';
+local prometheusAdapter = import './components/prometheus-adapter.libsonnet';
+local prometheusOperator = import './components/prometheus-operator.libsonnet';
+local prometheus = import './components/prometheus.libsonnet';
 
 {
   // using `values` as this is similar to helm
diff --git a/jsonnet/kube-prometheus/kube-prometheus-kube-aws.libsonnet b/jsonnet/kube-prometheus/platforms/aws.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/kube-prometheus-kube-aws.libsonnet
rename to jsonnet/kube-prometheus/platforms/aws.libsonnet
diff --git a/jsonnet/kube-prometheus/kube-prometheus-bootkube.libsonnet b/jsonnet/kube-prometheus/platforms/bootkube.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/kube-prometheus-bootkube.libsonnet
rename to jsonnet/kube-prometheus/platforms/bootkube.libsonnet
diff --git a/jsonnet/kube-prometheus/kube-prometheus-eks.libsonnet b/jsonnet/kube-prometheus/platforms/eks.libsonnet
similarity index 61%
rename from jsonnet/kube-prometheus/kube-prometheus-eks.libsonnet
rename to jsonnet/kube-prometheus/platforms/eks.libsonnet
index 3f6ab80dd9e80393a573ddbd860cf2e4b578e1af..c72e5c8ba219964e72396b945669e10f44969181 100644
--- a/jsonnet/kube-prometheus/kube-prometheus-eks.libsonnet
+++ b/jsonnet/kube-prometheus/platforms/eks.libsonnet
@@ -1,5 +1,5 @@
 {
-  _config+:: {
+  values+:: {
     eks: {
       minimumAvailableIPs: 10,
       minimumAvailableIPsTime: '10m',
@@ -39,7 +39,7 @@
       kind: 'ServiceMonitor',
       metadata: {
         name: 'awsekscni',
-        namespace: $._config.namespace,
+        namespace: $.values.common.namespace,
         labels: {
           'app.kubernetes.io/name': 'eks-cni',
         },
@@ -65,25 +65,34 @@
         ],
       },
     },
-  },
-  prometheusRules+: {
-    groups+: [
-      {
-        name: 'kube-prometheus-eks.rules',
-        rules: [
+    prometheusRuleEksCNI: {
+      apiVersion: 'monitoring.coreos.com/v1',
+      kind: 'PrometheusRule',
+      metadata: {
+        labels: $.prometheus.config.commonLabels + $.prometheus.config.mixin.ruleLabels,
+        name: 'eks-rules',
+        namespace: $.prometheus.config.namespace,
+      },
+      spec: {
+        groups: [
           {
-            expr: 'sum by(instance) (awscni_ip_max) - sum by(instance) (awscni_assigned_ip_addresses) < %s' % $._config.eks.minimumAvailableIPs,
-            labels: {
-              severity: 'critical',
-            },
-            annotations: {
-              message: 'Instance {{ $labels.instance }} has less than 10 IPs available.',
-            },
-            'for': $._config.eks.minimumAvailableIPsTime,
-            alert: 'EksAvailableIPs',
+            name: 'kube-prometheus-eks.rules',
+            rules: [
+              {
+                expr: 'sum by(instance) (awscni_ip_max) - sum by(instance) (awscni_assigned_ip_addresses) < %s' % $.values.eks.minimumAvailableIPs,
+                labels: {
+                  severity: 'critical',
+                },
+                annotations: {
+                  message: 'Instance {{ $labels.instance }} has less than 10 IPs available.',
+                },
+                'for': $.values.eks.minimumAvailableIPsTime,
+                alert: 'EksAvailableIPs',
+              },
+            ],
           },
         ],
       },
-    ],
+    },
   },
 }
diff --git a/jsonnet/kube-prometheus/kube-prometheus-gke.libsonnet b/jsonnet/kube-prometheus/platforms/gke.libsonnet
similarity index 73%
rename from jsonnet/kube-prometheus/kube-prometheus-gke.libsonnet
rename to jsonnet/kube-prometheus/platforms/gke.libsonnet
index 3d64c01476450630cb17cca2a2be152f83007c98..b8b83c28b471466c21c8ee6a662b68cc84f35f5b 100644
--- a/jsonnet/kube-prometheus/kube-prometheus-gke.libsonnet
+++ b/jsonnet/kube-prometheus/platforms/gke.libsonnet
@@ -1,4 +1,4 @@
-(import './kube-prometheus-managed-cluster.libsonnet') + {
+(import '../addons/managed-cluster.libsonnet') + {
   _config+:: {
     prometheusAdapter+:: {
       config+: {
diff --git a/jsonnet/kube-prometheus/kube-prometheus-kops-coredns.libsonnet b/jsonnet/kube-prometheus/platforms/kops-coredns.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/kube-prometheus-kops-coredns.libsonnet
rename to jsonnet/kube-prometheus/platforms/kops-coredns.libsonnet
diff --git a/jsonnet/kube-prometheus/kube-prometheus-kops.libsonnet b/jsonnet/kube-prometheus/platforms/kops.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/kube-prometheus-kops.libsonnet
rename to jsonnet/kube-prometheus/platforms/kops.libsonnet
diff --git a/jsonnet/kube-prometheus/kube-prometheus-kubeadm.libsonnet b/jsonnet/kube-prometheus/platforms/kubeadm.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/kube-prometheus-kubeadm.libsonnet
rename to jsonnet/kube-prometheus/platforms/kubeadm.libsonnet
diff --git a/jsonnet/kube-prometheus/kube-prometheus-kubespray.libsonnet b/jsonnet/kube-prometheus/platforms/kubespray.libsonnet
similarity index 100%
rename from jsonnet/kube-prometheus/kube-prometheus-kubespray.libsonnet
rename to jsonnet/kube-prometheus/platforms/kubespray.libsonnet