diff --git a/hack/grafana-dashboards-configmap-generator/README.md b/hack/grafana-dashboards-configmap-generator/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..cc4f51a3c483299c430e98bacdcdb956b913d9e3
--- /dev/null
+++ b/hack/grafana-dashboards-configmap-generator/README.md
@@ -0,0 +1,51 @@
+# Grafana Dashboards Configmap Generator
+
+## Description:
+Tool to maintain grafana dashboards' configmap for a grafana deployed with kube-prometheus (a tool inside prometheus-operator).
+
+The tool reads the content of a directory with grafana .json resources (dashboards and datasources) and creates a manifest file under output/ directory with all the content from the files in a Kubernetes ConfigMap format.
+
+Based on a configurable size limit, the tool will create 1 or N configmaps to allocate the .json resources (bin packing). If the limit is reached then the configmaps generated will have names like grafana-dashboards-0, grafana-dashboards-1, etc, and if the limit is not reached the configmap generated will be called "grafana-dashboards".
+
+Input Parameters Allowed:
+```bash
+-i dir, --input-dir dir
+  Directory with grafana dashboards to process.
+  Important notes:
+    Files should be suffixed with -dashboard.json or -datasource.json.
+    We don't recommend file names with spaces.
+
+-o file, --output-file file
+  Output file for config maps.
+
+-s NUM, --size-limit NUM
+  Size limit in bytes for each dashboard (default: 240000)
+
+-n namespace, --namespace namespace
+  Namespace for the configmap (default: monitoring).
+
+-x, --apply-configmap
+  Applies the generated configmap with kubectl.
+
+--apply-type
+  Type of kubectl command. Accepted values: apply, replace, create (default: apply).
+```
+
+## Usage
+
+Just execute the .sh under bin/ directory. The output will be placed in the output/ directory.
+
+Examples:
+```bash
+$ ./grafana_dashboards_generate.sh
+$ bin/grafana_dashboards_generate.sh -o manifests/grafana/grafana-dashboards.yaml -i assets/grafana-dashboards
+$ bin/grafana_dashboards_generate.sh -s 1000000 --apply-configmap --apply-type replace
+
+# Note: the output file, if provided with -o, shouldn't exist.
+```
+
+## Configuration and options
+
+* Put the json files you want to pack in the templates/grafana-dashboards/ directory
+* Size limit default is 240000 bytes due to the annotations size limit in kubernetes of 256KB.
+
diff --git a/hack/grafana-dashboards-configmap-generator/bin/grafana_dashboards_generate.sh b/hack/grafana-dashboards-configmap-generator/bin/grafana_dashboards_generate.sh
new file mode 100755
index 0000000000000000000000000000000000000000..91bcd4288c36002765299596242bbaf95111820d
--- /dev/null
+++ b/hack/grafana-dashboards-configmap-generator/bin/grafana_dashboards_generate.sh
@@ -0,0 +1,397 @@
+#!/bin/bash
+
+# exit immediately when a command fails
+set -e
+# only exit with zero if all commands of the pipeline exit successfully
+set -o pipefail
+# error on unset variables
+set -u
+
+# Author: eedugon
+
+# Description: Tool to maintain grafana dashboards configmap for a grafana deployed
+#   with kube-prometheus (a tool inside prometheus-operator)
+# The tool reads the content of a directory with grafana .json resources
+#   that need to be moved into a configmap.
+# Based on a configurable size limit, the tool will create 1 or N configmaps
+#   to allocate the .json resources (bin packing)
+
+# Update: 20170914
+# The tool also generates a grafana deployment manifest (-g option)
+
+# parameters
+# -o, --output-file
+# -g, --grafana-manifest-file
+# -i, --input-dir
+# -s, --size-limit
+# -x, --apply-configmap : true or false (default = false)
+# --apply-type : create, replace, apply (default = apply)
+
+#
+# Basic Functions
+#
+echoSyntax() {
+  echo "Usage: ${0} [options]"
+  echo "Options:"
+  echo -e "\t-i dir, --input-dir dir"
+  echo -e "\t\tDirectory with grafana dashboards to process."
+  echo -e "\t\tImportant notes:"
+  echo -e "\t\t\tFiles should be suffixed with -dashboard.json or -datasource.json."
+  echo -e "\t\t\tWe don't recommend file names with spaces."
+  echo
+  echo -e "\t-o file, --output-file file"
+  echo -e "\t\tOutput file for config maps."
+  echo
+  echo -e "\t-s NUM, --size-limit NUM"
+  echo -e "\t\tSize limit in bytes for each dashboard (default: 240000)"
+  echo
+  echo -e "\t-n namespace, --namespace namespace"
+  echo -e "\t\tNamespace for the configmap (default: monitoring)."
+  echo
+  echo -e "\t-x, --apply-configmap"
+  echo -e "\t\tApplies the generated configmap with kubectl."
+  echo
+  echo -e "\t--apply-type"
+  echo -e "\t\tType of kubectl command. Accepted values: apply, replace, create (default: apply)."
+}
+
+
+# # Apply changes --> environment allowed
+# test -z "$APPLY_CONFIGMAP" && APPLY_CONFIGMAP="false"
+# # Size limit --> environment set allowed
+# test -z "$DATA_SIZE_LIMIT" && DATA_SIZE_LIMIT="240000" # in bytes
+# # Changes type: in case of problems with k8s configmaps, try replace. Should be apply
+# test -z "$APPLY_TYPE" && APPLY_TYPE="apply"
+# # Input values verification
+# echo "$DATA_SIZE_LIMIT" | grep -q "^[0-9]\+$" || { echo "ERROR: Incorrect value for DATA_SIZE_LIMIT: $DATA_SIZE_LIMIT. Number expected"; exit 1; }
+
+# Base variables (do not change them)
+DATE_EXEC="$(date "+%Y-%m-%d-%H%M%S")"
+BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+TOOL_HOME="$(dirname $BIN_DIR)"
+SCRIPT_BASE=`basename $0 | sed "s/\.[Ss][Hh]//"`
+CONFIGMAP_DASHBOARD_PREFIX="grafana-dashboards"
+
+TEMPLATES_DIR="$TOOL_HOME/templates"
+DASHBOARD_HEADER_FILE="$TEMPLATES_DIR/dashboard.header"
+DASHBOARD_FOOT_FILE="$TEMPLATES_DIR/dashboard.foot"
+CONFIGMAP_HEADER="$TEMPLATES_DIR/ConfigMap.header"
+GRAFANA_DEPLOYMENT_TEMPLATE="$TEMPLATES_DIR/grafana-deployment-template.yaml"
+OUTPUT_BASE_DIR="$TOOL_HOME/output"
+
+# Some default values
+OUTPUT_FILE="$OUTPUT_BASE_DIR/grafana-dashboards-configMap-$DATE_EXEC.yaml"
+GRAFANA_OUTPUT_FILE="$OUTPUT_BASE_DIR/grafana-deployment-$DATE_EXEC.yaml"
+DASHBOARDS_DIR="$TEMPLATES_DIR/grafana-dashboards"
+
+APPLY_CONFIGMAP="false"
+APPLY_TYPE="apply"
+DATA_SIZE_LIMIT="240000"
+NAMESPACE="monitoring"
+
+# Input parameters
+while (( "$#" )); do
+    case "$1" in
+        "-o" | "--output-file")
+            OUTPUT_FILE="$2"
+            shift
+            ;;
+        "-g" | "--grafana-output-file")
+            GRAFANA_OUTPUT_FILE="$2"
+            shift
+            ;;
+        "-i" | "--input-dir")
+            DASHBOARDS_DIR="$2"
+            shift
+            ;;
+        "-n" | "--namespace")
+            NAMESPACE="$2"
+            shift
+            ;;
+        "-x" | "--apply-configmap")
+            APPLY_CONFIGMAP="true"
+            ;;
+        "--apply-type")
+            APPLY_TYPE="$2"
+            test "$APPLY_TYPE" != "create" && test "$APPLY_TYPE" != "apply" && test "$APPLY_TYPE" != "replace" && { echo "Unexpected APPLY_TYPE: $APPLY_TYPE"; exit 1; }
+            shift
+            ;;
+        "-s"|"--size-limit")
+            if ! ( echo $2 | grep -q '^[0-9]\+$') || [ $2 -eq 0 ]; then
+                echo "Invalid value for size limit '$2'"
+                exit 1
+            fi
+            DATA_SIZE_LIMIT=$2
+            shift
+            ;;
+        "-h"|"--help")
+            echoSyntax
+            exit 0
+            ;;
+        *)
+            echo "Unknown argument: $1"
+            exit 1
+            ;;
+    esac
+    shift
+done
+
+#
+# Auxiliary Functions
+#
+indentMultiLineString() {
+    # Indent a given string (in one line including multiple \n)
+    test "$#" -eq 2 || { echo "INTERNAL ERROR: wrong call to function indentMultiLineString"; exit 1; }
+    local indent_number="$1"
+    local string="$2"
+
+    test "$indent_number" -ge 0 || { echo "INTERNAL ERROR: wrong indent number parameter: $indent_number"; exit 1; }
+
+    # prepare indentation text
+    local indent_string=""
+    for (( c=0; c<$indent_number; c++ )); do
+      indent_string="$indent_string "
+    done
+
+    echo "$string" | sed -e "s#^#$indent_string#" -e "s#\\\n#\\\n$indent_string#g"
+}
+
+#
+# Main Functions
+#
+addConfigMapHeader() {
+  # If a parameter is provided it will be used as the configmap index.
+  # If no parameter is provided, the name will be kept
+  test "$#" -le 1 || { echo "# INTERNAL ERROR: Wrong call to function addConfigMapHeader"; return 1; }
+  test "$#" -eq 1 && local id="$1" || local id=""
+
+  if [ "$id" ]; then
+    cat "$CONFIGMAP_HEADER" | sed "s/name: $CONFIGMAP_DASHBOARD_PREFIX/name: $CONFIGMAP_DASHBOARD_PREFIX-$id/"
+  else
+    cat "$CONFIGMAP_HEADER"
+  fi
+}
+
+addArrayToConfigMap() {
+  # This function process the array to_process into a configmap
+
+  local OLDIFS=$IFS
+  local IFS=$'\n'
+  for file in ${to_process[@]}; do
+    # check that file exists
+    test -f "$file" || { echo "# INTERNAL ERROR IN ARRAY: File not found: $file"; continue; }
+
+    # detection of type (dashboard or datasource)
+    type=""
+    basename "$file" | grep -q "\-datasource" && type="datasource"
+    basename "$file" | grep -q "\-dashboard" && type="dashboard"
+    test "$type" || { echo "# ERROR: Unrecognized file type: $(basename $file)"; return 1; }
+
+    #echo "# Processing $type $file"
+    # Indent 2
+    echo "  $(basename $file): |+"
+
+    # Dashboard header: No indent needed
+    test "$type" = "dashboard" && cat $DASHBOARD_HEADER_FILE
+
+    # File content: Indent 4
+    cat $file | sed "s/^/    /"
+
+    # Dashboard foot
+    test "$type" = "dashboard" && cat $DASHBOARD_FOOT_FILE
+  done
+  echo "---"
+
+  IFS=$OLDIFS
+  return 0
+}
+
+initialize-bin-pack() {
+  # We separate initialization to reuse the bin-pack for different sets of files.
+  n="0"
+  to_process=()
+  bytes_to_process="0"
+  total_files_processed="0"
+  total_configmaps_created="0"
+}
+
+bin-pack-files() {
+  # Algorithm:
+  # We process the files with no special order consideration
+  # We create an array/queue of "files to add to configmap" called "to_process"
+  # Size of the file is analyzed to determine if it can be added to the queue or not.
+  # the max size of the queue is limited by DATA_SIZE_LIMIT
+  # while there's room available in the queue we add files.
+  # when there's no room we create a configmap with the members of the queue
+  #  before adding the file to a cleaned queue
+
+  # Counters initialization is not in the scope of this function
+  local file=""
+  OLDIFS=$IFS
+  IFS=$'\n'
+#  echo "DEBUG bin-pack:"
+#  echo "$@"
+
+  for file in $@; do
+    test -f "$file" || { echo "# INTERNAL ERROR: File not found: $file"; continue; }
+#    echo "debug: Processing file $(basename $file)"
+
+    file_size_bytes="$(stat -c%s "$file")" || true
+
+    # If the file is bigger than the configured limit we skip it file
+    if [ "$file_size_bytes" -gt "$DATA_SIZE_LIMIT" ]; then
+      echo "ERROR: File $(basename $file) bigger than size limit: $DATA_SIZE_LIMIT ($file_size_bytes). Skipping"
+      continue
+    fi
+    (( total_files_processed++ )) || true
+
+    if test "$(expr "$bytes_to_process" + "$file_size_bytes")" -le "$DATA_SIZE_LIMIT"; then
+      # We have room to include the file in the configmap
+      # test "$to_process" && to_process="$to_process $file" || to_process="$file"
+      to_process+=("$file")
+      (( bytes_to_process = bytes_to_process + file_size_bytes )) || true
+      echo "# File $(basename $file) : added to queue"
+    else
+      # There's no room to add this file to the queue. so we process what we have and add the file to the queue
+      if [ "$to_process" ]; then
+        echo
+        echo "# Size limit ($DATA_SIZE_LIMIT) reached. Processing queue with $bytes_to_process bytes. Creating configmap with id $n"
+        echo
+        # Create a new configmap
+        addConfigMapHeader $n >> $OUTPUT_FILE || { echo "ERROR in call to addConfigMapHeader function"; exit 1; }
+        addArrayToConfigMap >> $OUTPUT_FILE || { echo "ERROR in call to addArrayToConfigMap function"; exit 1; }
+        # Initialize variables with info about file not processed
+        (( total_configmaps_created++ )) || true
+        (( n++ )) || true
+        # to_process="$file"
+        to_process=()
+        to_process+=("$file")
+        bytes_to_process="$file_size_bytes"
+        echo "# File $(basename $file) : added to queue"
+      else
+        # based on the algorithm the queue should never be empty if we reach this part of the code
+        # if this happens maybe bytes_to_process was not aligned with the queue (to_process)
+        echo "ERROR (unexpected)"
+      fi
+    fi
+  done
+  IFS=$OLDIFS
+}
+
+# prepareGrafanaDeploymentManifest() {
+#   local num_configmaps="$1"
+#
+#   for (( i=0; i<$total_configmaps_created; i++ )); do
+#     echo "Creating deployment for $CONFIGMAP_DASHBOARD_PREFIX-$i"
+#
+#   done
+# }
+
+
+# Some variables checks...
+test ! -d "$TEMPLATES_DIR" && { echo "ERROR: missing templates directory $TEMPLATES_DIR"; exit 1; }
+
+test -f "$DASHBOARD_FOOT_FILE" || { echo "Template $DASHBOARD_FOOT_FILE not found"; exit 1; }
+test -f "$DASHBOARD_HEADER_FILE" || { echo "Template $DASHBOARD_HEADER_FILE not found"; exit 1; }
+test -f "$CONFIGMAP_HEADER" || { echo "Template $CONFIGMAP_HEADER not found"; exit 1; }
+test -f "$GRAFANA_DEPLOYMENT_TEMPLATE" || { echo "Template $GRAFANA_DEPLOYMENT_TEMPLATE not found"; exit 1; }
+
+test ! -d "$OUTPUT_BASE_DIR" && { echo "ERROR: missing directory $OUTPUT_BASE_DIR"; exit 1; }
+
+# Initial checks
+test -d "$DASHBOARDS_DIR" || { echo "ERROR: Dashboards directory not found: $DASHBOARDS_DIR"; echoSyntax; exit 1; }
+
+test -f "$OUTPUT_FILE" && { echo "ERROR: Output file already exists: $OUTPUT_FILE"; exit 1; }
+test -f "$GRAFANA_OUTPUT_FILE" && { echo "ERROR: Output file already exists: $GRAFANA_OUTPUT_FILE"; exit 1; }
+touch $OUTPUT_FILE || { echo "ERROR: Unable to create or modify $OUTPUT_FILE"; exit 1; }
+touch $GRAFANA_OUTPUT_FILE || { echo "ERROR: Unable to create or modify $GRAFANA_OUTPUT_FILE"; exit 1; }
+
+# Main code start
+
+echo "# Starting execution of $SCRIPT_BASE on $DATE_EXEC"
+echo "# Configured size limit: $DATA_SIZE_LIMIT bytes"
+echo "# Grafna input dashboards and datasources will be read from: $DASHBOARDS_DIR"
+echo "# Grafana Dashboards ConfigMap will be created into file:"
+echo "$OUTPUT_FILE"
+echo "# Grafana Deployment manifest will be created into file:"
+echo "$GRAFANA_OUTPUT_FILE"
+echo
+
+# Loop variables initialization
+initialize-bin-pack
+
+# Process dashboards
+bin-pack-files "$(find $DASHBOARDS_DIR -maxdepth 1 -type f -name "*-dashboard.json" | sort)"
+
+# Continue processing datasources (maintaining the same queue)
+bin-pack-files "$(find $DASHBOARDS_DIR -maxdepth 1 -type f -name "*-datasource.json" | sort )"
+
+# Processing remaining data in the queue (or unique)
+if [ "$to_process" ]; then
+  if [ "$n" -eq 0 ]; then
+    echo
+    echo "# Size limit not reached ($bytes_to_process). Adding all files into basic configmap"
+    echo
+    addConfigMapHeader $n >> $OUTPUT_FILE || { echo "ERROR in call to addConfigMapHeader function"; exit 1; }
+  else
+    echo
+    echo "# Size limit not reached ($bytes_to_process). Adding remaining files into configmap with id $n"
+    echo
+    addConfigMapHeader $n >> $OUTPUT_FILE || { echo "ERROR in call to addConfigMapHeader function"; exit 1; }
+  fi
+  addArrayToConfigMap >> $OUTPUT_FILE || { echo "ERROR in call to addArrayToConfigMap function"; exit 1; }
+  (( total_configmaps_created++ )) || true
+  to_process=()
+fi
+
+echo "# Process completed, configmap created: $(basename $OUTPUT_FILE)"
+echo "# Summary"
+echo "# Total files processed: $total_files_processed"
+echo "# Total amount of ConfigMaps inside the manifest: $total_configmaps_created"
+echo
+# Grafana deployment Processing (for every configmap)
+#prepareGrafanaDeploymentManifest "$total_configmaps_created"
+VOLUMES=""
+VOLUME_MOUNTS=""
+WATCH_DIR=""
+for (( i=0; i<$total_configmaps_created; i++ )); do
+  configmap="$CONFIGMAP_DASHBOARD_PREFIX-$i"
+  echo "# Preparing grafana deployment to support configmap: $configmap"
+
+  test "$VOLUME_MOUNTS" && VOLUME_MOUNTS="$VOLUME_MOUNTS\n- name: $configmap\n  mountPath: /var/$configmap" || VOLUME_MOUNTS="- name: $configmap\n  mountPath: /var/$configmap"
+  test "$VOLUMES" && VOLUMES="$VOLUMES\n- name: $configmap\n  configMap:\n    name: $configmap" || VOLUMES="- name: $configmap\n  configMap:\n    name: $configmap"
+  test "$WATCH_DIR" && WATCH_DIR="$WATCH_DIR\n- '--watch-dir=/var/$configmap'" || WATCH_DIR="- '--watch-dir=/var/$configmap'"
+  # echo "DEBUG:"
+  # echo "VOLUMES: $VOLUMES"
+  # echo "VOLUME_MOUNTS: $VOLUME_MOUNTS"
+  # echo "WATCH_DIR: $WATCH_DIR"
+  echo
+done
+
+echo "# Processing grafana deployment template into $GRAFANA_OUTPUT_FILE"
+sed -e "s#XXX_VOLUMES_XXX#$(indentMultiLineString 6 "$VOLUMES")#" \
+   -e "s#XXX_VOLUME_MOUNTS_XXX#$(indentMultiLineString 8 "$VOLUME_MOUNTS")#" \
+   -e "s#XXX_WATCH_DIR_XXX#$(indentMultiLineString 10 "$WATCH_DIR")#" \
+   $GRAFANA_DEPLOYMENT_TEMPLATE > $GRAFANA_OUTPUT_FILE
+
+# If output file is empty we can delete it and exit
+test ! -s "$OUTPUT_FILE" && { echo "# Configmap empty, deleting file"; rm $OUTPUT_FILE; exit 0; }
+test ! -s "$GRAFANA_OUTPUT_FILE" && { echo "# Configmap empty, deleting file"; rm $GRAFANA_OUTPUT_FILE; exit 0; }
+
+if [ "$APPLY_CONFIGMAP" = "true" ]; then
+  test -x "$(which kubectl)" || { echo "ERROR: kubectl command not available. Apply configmap not possible"; exit 1; }
+  echo "# Applying configuration with $APPLY_TYPE method on namespace $NAMESPACE"
+  if kubectl -n $NAMESPACE $APPLY_TYPE -f "$OUTPUT_FILE"; then
+    echo
+    echo "# ConfigMap updated. Updating grafana deployment"
+    kubectl -n $NAMESPACE $APPLY_TYPE -f "$GRAFANA_OUTPUT_FILE" || { echo "Error applying Grafana deployment. Check yaml file: $GRAFANA_OUTPUT_FILE"; exit 1; }
+  else
+    echo "Error applying Configmap. Check yaml file: $OUTPUT_FILE"
+  fi
+else
+  echo
+  echo "# To apply the new configMap to your k8s system do something like:"
+  echo "kubectl -n monitoring $APPLY_TYPE -f $OUTPUT_FILE"
+  echo "kubectl -n monitoring $APPLY_TYPE -f $GRAFANA_OUTPUT_FILE"
+  echo
+fi
diff --git a/hack/grafana-dashboards-configmap-generator/output/README.md b/hack/grafana-dashboards-configmap-generator/output/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..d2e3c8a66a3c8d261716abfea0fd5f3f8bef0312
--- /dev/null
+++ b/hack/grafana-dashboards-configmap-generator/output/README.md
@@ -0,0 +1 @@
+### This directory will include all generated manifests if no specific options are given
diff --git a/hack/grafana-dashboards-configmap-generator/templates/ConfigMap.header b/hack/grafana-dashboards-configmap-generator/templates/ConfigMap.header
new file mode 100644
index 0000000000000000000000000000000000000000..afc1f42cbfe862f18eaf5d7e0e19750687f59218
--- /dev/null
+++ b/hack/grafana-dashboards-configmap-generator/templates/ConfigMap.header
@@ -0,0 +1,5 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: grafana-dashboards
+data:
diff --git a/hack/grafana-dashboards-configmap-generator/templates/dashboard.foot b/hack/grafana-dashboards-configmap-generator/templates/dashboard.foot
new file mode 100644
index 0000000000000000000000000000000000000000..81fe9f6fd7de318bb42f0e6884bcf9e6332740ac
--- /dev/null
+++ b/hack/grafana-dashboards-configmap-generator/templates/dashboard.foot
@@ -0,0 +1,11 @@
+    ,
+      "inputs": [
+        {
+          "name": "DS_PROMETHEUS",
+          "pluginId": "prometheus",
+          "type": "datasource",
+          "value": "prometheus"
+        }
+      ],
+      "overwrite": true
+    }
diff --git a/hack/grafana-dashboards-configmap-generator/templates/dashboard.header b/hack/grafana-dashboards-configmap-generator/templates/dashboard.header
new file mode 100644
index 0000000000000000000000000000000000000000..807e5d38caf69d3642c74e088a527df7192c1df6
--- /dev/null
+++ b/hack/grafana-dashboards-configmap-generator/templates/dashboard.header
@@ -0,0 +1,2 @@
+    {
+      "dashboard":
diff --git a/hack/grafana-dashboards-configmap-generator/templates/grafana-dashboards/README.md b/hack/grafana-dashboards-configmap-generator/templates/grafana-dashboards/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..69be0eec84ad17f5bca5c953deb569abdffdb270
--- /dev/null
+++ b/hack/grafana-dashboards-configmap-generator/templates/grafana-dashboards/README.md
@@ -0,0 +1 @@
+# Add your grafana dashboards into this directory
diff --git a/hack/grafana-dashboards-configmap-generator/templates/grafana-deployment-template.yaml b/hack/grafana-dashboards-configmap-generator/templates/grafana-deployment-template.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..844ecbc7aa032d7760cbe158af4e9b5e7cd854b5
--- /dev/null
+++ b/hack/grafana-dashboards-configmap-generator/templates/grafana-deployment-template.yaml
@@ -0,0 +1,71 @@
+apiVersion: apps/v1beta1
+kind: Deployment
+metadata:
+  name: grafana
+spec:
+  replicas: 1
+  template:
+    metadata:
+      labels:
+        app: grafana
+    spec:
+      containers:
+      - name: grafana
+        image: grafana/grafana:4.4.1
+        env:
+        - name: GF_AUTH_BASIC_ENABLED
+          value: "true"
+        - name: GF_AUTH_ANONYMOUS_ENABLED
+          value: "true"
+        - name: GF_SECURITY_ADMIN_USER
+          valueFrom:
+            secretKeyRef:
+              name: grafana-credentials
+              key: user
+        - name: GF_SECURITY_ADMIN_PASSWORD
+          valueFrom:
+            secretKeyRef:
+              name: grafana-credentials
+              key: password
+        volumeMounts:
+        - name: grafana-storage
+          mountPath: /var/grafana-storage
+        ports:
+        - name: web
+          containerPort: 3000
+        resources:
+          requests:
+            memory: 100Mi
+            cpu: 100m
+          limits:
+            memory: 200Mi
+            cpu: 200m
+      - name: grafana-watcher
+        image: quay.io/coreos/grafana-watcher:v0.0.8
+        args:
+XXX_WATCH_DIR_XXX
+          - '--grafana-url=http://localhost:3000'
+        env:
+        - name: GRAFANA_USER
+          valueFrom:
+            secretKeyRef:
+              name: grafana-credentials
+              key: user
+        - name: GRAFANA_PASSWORD
+          valueFrom:
+            secretKeyRef:
+              name: grafana-credentials
+              key: password
+        resources:
+          requests:
+            memory: "16Mi"
+            cpu: "50m"
+          limits:
+            memory: "32Mi"
+            cpu: "100m"
+        volumeMounts:
+XXX_VOLUME_MOUNTS_XXX
+      volumes:
+      - name: grafana-storage
+        emptyDir: {}
+XXX_VOLUMES_XXX
diff --git a/hack/scripts/generate-manifests.sh b/hack/scripts/generate-manifests.sh
index 280bc121e6666f35707a87364855fb6992d26af6..bb0c0685695abf5b0a618d2a72683ea137ba0e02 100755
--- a/hack/scripts/generate-manifests.sh
+++ b/hack/scripts/generate-manifests.sh
@@ -4,7 +4,16 @@
 hack/scripts/generate-rules-configmap.sh > manifests/prometheus/prometheus-k8s-rules.yaml
 
 # Generate Dashboard ConfigMap
-hack/scripts/generate-dashboards-configmap.sh > manifests/grafana/grafana-dashboards.yaml
+#hack/scripts/generate-dashboards-configmap.sh > manifests/grafana/grafana-dashboards.yaml
+
+# Generate Dashboard ConfigMap with configmap-generator tool
+# Max Size per ConfigMap: 240000
+# Input dir: assets/grafana
+# output file: manifests/grafana/grafana-dashboards.yaml
+# grafana deployment output file: manifests/grafana/grafana-deployment.yaml
+test -f manifests/grafana/grafana-dashboards.yaml && rm -f manifests/grafana/grafana-dashboards.yaml
+test -f manifests/grafana/grafana-deployment.yaml && rm -f manifests/grafana/grafana-deployment.yaml
+hack/grafana-dashboards-configmap-generator/bin/grafana_dashboards_generate.sh -s 240000 -i assets/grafana -o manifests/grafana/grafana-dashboards.yaml -g manifests/grafana/grafana-deployment.yaml
 
 # Generate Grafana Credentials Secret
 hack/scripts/generate-grafana-credentials-secret.sh admin admin > manifests/grafana/grafana-credentials.yaml
diff --git a/manifests/grafana/grafana-dashboards.yaml b/manifests/grafana/grafana-dashboards.yaml
index f7903dc2131dcf29ee9bc3896131266b6aa863f6..36ac037302e19d982cd55dbca443dc89567b118b 100644
--- a/manifests/grafana/grafana-dashboards.yaml
+++ b/manifests/grafana/grafana-dashboards.yaml
@@ -1,7 +1,7 @@
 apiVersion: v1
 kind: ConfigMap
 metadata:
-  name: grafana-dashboards
+  name: grafana-dashboards-0
 data:
   deployment-dashboard.json: |+
     {
@@ -821,7 +821,7 @@ data:
       "timezone": "browser",
       "title": "Deployment",
       "version": 1
-    },
+    }    ,
       "inputs": [
         {
           "name": "DS_PROMETHEUS",
@@ -1882,7 +1882,7 @@ data:
       "timezone": "browser",
       "title": "Kubernetes Capacity Planing",
       "version": 4
-    },
+    }    ,
       "inputs": [
         {
           "name": "DS_PROMETHEUS",
@@ -2628,7 +2628,7 @@ data:
       "timezone": "",
       "title": "Kubernetes Cluster Health",
       "version": 12
-    },
+    }    ,
       "inputs": [
         {
           "name": "DS_PROMETHEUS",
@@ -3537,7 +3537,7 @@ data:
       "timezone": "",
       "title": "Kubernetes Cluster Status",
       "version": 22
-    },
+    }    ,
       "inputs": [
         {
           "name": "DS_PROMETHEUS",
@@ -4213,7 +4213,7 @@ data:
       "timezone": "",
       "title": "Kubernetes Control Plane Status",
       "version": 11
-    },
+    }    ,
       "inputs": [
         {
           "name": "DS_PROMETHEUS",
@@ -4660,7 +4660,7 @@ data:
       "timezone": "browser",
       "title": "Kubernetes Resource Requests",
       "version": 2
-    },
+    }    ,
       "inputs": [
         {
           "name": "DS_PROMETHEUS",
@@ -5565,7 +5565,7 @@ data:
       "timezone": "browser",
       "title": "Nodes",
       "version": 2
-    },
+    }    ,
       "inputs": [
         {
           "name": "DS_PROMETHEUS",
@@ -6010,7 +6010,7 @@ data:
       "timezone": "browser",
       "title": "Pods",
       "version": 1
-    },
+    }    ,
       "inputs": [
         {
           "name": "DS_PROMETHEUS",
@@ -6029,3 +6029,4 @@ data:
         "type": "prometheus",
         "url": "http://prometheus-k8s.monitoring.svc:9090"
     }
+---
diff --git a/manifests/grafana/grafana-deployment.yaml b/manifests/grafana/grafana-deployment.yaml
index 1666deaee1141a489eab265a274830f51d14559f..a75724e59e1c0461900d0b8cd9a12dbfbf798c06 100644
--- a/manifests/grafana/grafana-deployment.yaml
+++ b/manifests/grafana/grafana-deployment.yaml
@@ -43,7 +43,7 @@ spec:
       - name: grafana-watcher
         image: quay.io/coreos/grafana-watcher:v0.0.8
         args:
-          - '--watch-dir=/var/grafana-dashboards'
+          - '--watch-dir=/var/grafana-dashboards-0'
           - '--grafana-url=http://localhost:3000'
         env:
         - name: GRAFANA_USER
@@ -64,11 +64,11 @@ spec:
             memory: "32Mi"
             cpu: "100m"
         volumeMounts:
-        - name: grafana-dashboards
-          mountPath: /var/grafana-dashboards
+        - name: grafana-dashboards-0
+          mountPath: /var/grafana-dashboards-0
       volumes:
       - name: grafana-storage
         emptyDir: {}
-      - name: grafana-dashboards
+      - name: grafana-dashboards-0
         configMap:
-          name: grafana-dashboards
+          name: grafana-dashboards-0