Kubecost logo

Backstage Kubecost Plugin

Created by suxess-it

Kubecost helps you understand the cost of running Kubernetes. It turns cluster usage into costs you can trust. It can estimate future spend so you can plan. Many teams use it to track spend by workload, namespace, or label. That context is what you bring into Backstage with this plugin.

The Kubecost plugin adds cost views to your Backstage entities. It links a service in the catalog to its Kubernetes deployment through a simple annotation. Then it shows recent usage and cost for that service. You can switch between common time ranges. You can see totals and averages that match your currency settings. If your service runs in more than one cluster, the plugin can show costs from each place in one view. A direct link to your Kubecost dashboard can appear when you need deeper drill downs.

Use it to give service owners a clear view of what their code costs. Use it to spot unexpected spend after a deploy. Use it to compare environments or shared namespaces. Use it during on call to check if a surge in traffic is driving cost. It brings FinOps signals to the same spot where engineers already work.

Installation Instructions

These instructions apply to self-hosted Backstage only.

Step 1 Install Kubecost

Install Kubecost in your cluster. Enable Annotation Emission. Configure a cost model for your cloud or for on premises. Optional set up network cost allocation if you need network costs.

Links

Step 2 Add the plugin to your Backstage frontend

This plugin is frontend only. There is no backend package to install. It requires React 18 or newer.

Run this from the Backstage root

Copy
yarn add --cwd packages/app @suxess-it/backstage-plugin-kubecost

Step 3 Configure app config

Add a kubecost section in app-config.yaml. Set baseUrl to the Kubecost API endpoint you want to use. Add optional settings if needed.

Copy
# app-config.yaml
kubecost:
  baseUrl: https://kubecost.example.com   # required
  sharedNamespaces: team-a,team-b          # optional
  queryframes: week,yesterday,month,today,lastweek   # optional
  unitprefix: '€'                          # optional default is €
  fractionDigits: 4                        # optional default is 4
  annotationDeploymentName: 'backstage.io/kubernetes-id'  # optional default is kubecost.com/deployment-name
  shareTenancyCosts: true                  # optional default is false
  aggregate: true                          # optional default is false
  showDashboardLink: true                  # optional default is false

Step 4 Add the Kubecost page to the service entity page

Import the page component and the availability helper. Add a route under the Service entity layout. Place this in packages app src components catalog EntityPage.tsx

Copy
// packages/app/src/components/catalog/EntityPage.tsx

import React from 'react';
import { EntityLayout, EntitySwitch } from '@backstage/plugin-catalog';
import {
  BackstagePluginKubecostPage,
  isKubecostAvailable,
} from '@suxess-it/backstage-plugin-kubecost';

// your existing imports and page setup above

const serviceEntityPage = (
  <EntityLayout>
    {/* your existing routes */}
    <EntityLayout.Route if={isKubecostAvailable} path="/kubecost" title="Kubecost">
      <BackstagePluginKubecostPage />
    </EntityLayout.Route>
  </EntityLayout>
);

// export or use serviceEntityPage as in your app

Users will see a Kubecost tab for services that have the annotation set.

Step 5 Show a small cost card on the overview

Import the card and render it in the overview content for entities where Kubecost is available. Place this in the same EntityPage.tsx file where you define the overview content

Copy
// packages/app/src/components/catalog/EntityPage.tsx

import React from 'react';
import { EntitySwitch } from '@backstage/plugin-catalog';
import {
  EntityKubecostCard,
  isKubecostAvailable,
} from '@suxess-it/backstage-plugin-kubecost';

// somewhere inside your overview section
const overviewContent = (
  <>
    {/* your existing overview widgets */}
    <EntitySwitch>
      <EntitySwitch.Case if={isKubecostAvailable}>
        <EntityKubecostCard />
      </EntitySwitch.Case>
    </EntitySwitch>
  </>
);

The card shows last week usage to cost.

Step 6 Annotate your Backstage entities

Add an annotation on each entity that should show Kubecost data. The key must match the annotationDeploymentName you set in app config. The value must match a label on your Kubernetes Deployment

Copy
# catalog-info.yaml for your service
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: my-service
  annotations:
    backstage.io/kubernetes-id: my-service
spec:
  type: service
  owner: team-a
  lifecycle: production

Step 7 Label your Kubernetes Deployment

Add a label on your Deployment with the same key and value. This lets the plugin match the entity to the workload. If you used backstage.io/kubernetes-id in app config then label like this

Copy
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-service
  labels:
    app: my-service
    backstage.io/kubernetes-id: my-service
spec:
  selector:
    matchLabels:
      app: my-service
  template:
    metadata:
      labels:
        app: my-service
        backstage.io/kubernetes-id: my-service
    spec:
      containers:
        - name: my-service
          image: ghcr.io/my-org/my-service:latest

If the deployment runs in more than one cluster the plugin will show costs from each cluster.

Step 8 Optional tuning

You can adjust how costs are grouped and displayed

  • sharedNamespaces share costs across these namespaces
  • queryframes control time ranges such as week month yesterday today lastweek
  • unitprefix sets the currency symbol
  • fractionDigits sets decimals for costs and averages
  • shareTenancyCosts include shared tenancy costs
  • aggregate group costs by controller
  • showDashboardLink show a link to the Kubecost web UI based on baseUrl

Example

Copy
kubecost:
  baseUrl: https://kubecost.example.com
  sharedNamespaces: shared,platform
  queryframes: week,month
  unitprefix: '$'
  fractionDigits: 2
  shareTenancyCosts: true
  aggregate: true
  showDashboardLink: true

Backend setup

New backend system

No backend package to install. The plugin reads from the Kubecost API using the baseUrl you set in app config. You do not add anything to the new backend system

Old backend system

No backend package to install. You do not add anything to packages backend

Notes on multi cluster

The plugin supports multiple clusters. Use the same label key and value on each Deployment across clusters. The page will show costs per cluster automatically

Changelog

The Kubecost plugin has not seen any significant changes since 6 months ago.

Set up Backstage in minutes with Roadie