Skip to content
Grafana Dashboards

Grafana Dashboards

Grafana Dashboards

Visualize OpenShift cost data from the Koku API directly in Grafana using pre-built dashboard templates.

Source code: grafana-dashboard-sample

Overview

Three dashboard variants show daily OpenShift cost per project, sourced from the Cost Management report API. Each variant handles authentication and data transformation differently — pick the one that fits your infrastructure.

    graph LR
    A[Cost Management API] -->|OAuth2| B[Grafana<br/>Infinity Plugin]
    A -->|OAuth2| C[Flask Proxy]
    A -->|OAuth2| D[json_exporter]
    C --> B
    D --> E[Prometheus]
    E --> F[Grafana<br/>PromQL]
  

Dashboard Variants

VariantComplexityDependenciesBest For
Native (JSONata)LowGrafana + Infinity pluginQuick setup, minimal infrastructure
Flask ProxyMediumGrafana + Infinity + Python/FlaskNetwork-restricted Grafana instances
json_exporter + PrometheusHigherjson_exporter + Prometheus + GrafanaExisting Prometheus stack, alerting

Variant 1: Native (JSONata) — Simplest

Grafana queries the Cost Management API directly via the Infinity datasource. A JSONata expression flattens the nested API response into rows:

$.data.projects.values.{"date": date, "project": project, "cost": cost.total.value}

The Grafana time picker drives the API start_date / end_date parameters.

Setup:

cd dashboard_native
export COSTMGMT_CLIENT_ID="your-client-id"
export COSTMGMT_CLIENT_SECRET="your-client-secret"
bash import_dashboard.sh

Requires: Grafana + Infinity plugin v3.x. Nothing else.

Variant 2: Flask Proxy

A small Python server handles OAuth2 authentication and returns a pre-flattened JSON array. Useful when Grafana cannot reach the Cost Management API directly (network restrictions, firewall rules).

Setup:

cd dashboard_with_proxy
pip3 install flask requests
export COSTMGMT_CLIENT_ID="your-client-id"
export COSTMGMT_CLIENT_SECRET="your-client-secret"
nohup python3 cost_proxy.py > /tmp/cost_proxy.log 2>&1 &
bash import_dashboard.sh

Requires: Grafana + Infinity plugin, Python 3.8+ with flask and requests.

Variant 3: json_exporter + Prometheus

Cost data is scraped by json_exporter, stored in Prometheus, and queried via PromQL. This variant enables alerting and historical data retention beyond the API’s 90-day window.

Setup:

cd dashboard_with_json_exporter
export COSTMGMT_CLIENT_ID="your-client-id"
export COSTMGMT_CLIENT_SECRET="your-client-secret"
envsubst < json_exporter_config.yml > /tmp/json_exporter_config.yml
json_exporter --config.file=/tmp/json_exporter_config.yml &
# Add prometheus_scrape.yml to your prometheus.yml, reload Prometheus
bash import_dashboard.sh

Requires: json_exporter v0.7+, Prometheus, Grafana. No Infinity plugin needed.

The json_exporter variant’s time range is fixed at 30 days. The Grafana time picker does not affect it — Prometheus scrapes on a fixed schedule. Give it several days to build a meaningful trend line.

Feature Comparison

FeatureNativeProxyjson_exporter
Grafana time picker controls rangeYesYesNo (fixed 30d)
External dependenciesNonePython + Flaskjson_exporter + Prometheus
Data persistenceNone (live calls)None (live calls)Prometheus TSDB
Historical data beyond API rangeNoNoYes
PromQL alertingNoNoYes
Works if Grafana can’t reach APINoYesYes

Prerequisites

Credentials are never stored in dashboard.json files. All variants read from environment variables, falling back to placeholder values in the config files.

API Endpoint Used

All variants query the same Koku endpoint:

GET /api/cost-management/v1/reports/openshift/costs/
  ?filter[resolution]=daily
  &filter[time_scope_value]=-30
  &group_by[project]=*

The response is a nested tree: data[] → projects[] → values[] → cost.total.value. Each variant handles flattening differently.

Troubleshooting

SymptomCauseFix
“URL not allowed” in GrafanaMissing allowed hosts in Infinity datasourceRe-run import_dashboard.sh
Chart blank with narrow time rangeOnly 1 data point per seriesWiden time picker to ≥ 2 days
401 from APIWrong credentialsCheck COSTMGMT_CLIENT_ID / COSTMGMT_CLIENT_SECRET
All costs are $0No cost model assignedAssign a cost model with rates in Cost Management
json_exporter: “No data”Prometheus hasn’t scraped yetWait 15 min, check /targets

Extending

The sample dashboards show OpenShift costs grouped by project. To add panels for AWS, Azure, or GCP:

  1. Add a new Infinity datasource query pointing to the appropriate report endpoint (e.g., /reports/aws/costs/)
  2. Adjust the JSONata expression or proxy logic for the provider’s response structure
  3. Add new dashboard panels with the desired grouping

Further Reading