InfraWallet brings cloud cost visibility into your Backstage portal. It aggregates reports from AWS, Azure, Google Cloud, Confluent Cloud, Datadog, Elastic, GitHub, and MongoDB Atlas. It normalizes provider data so you can view costs in one place. You can group by account, provider, category, service, or tags. Cached data keeps pages fast. You can record custom costs when an integration is not available.
The plugin fits teams that want a shared picture of spend without leaving Backstage. Track monthly trends by team or service. Compare environments during a migration. Validate tag hygiene. Give product owners a simple view of what changed this quarter. Support FinOps workflows where engineers work.
If your goal is to give engineers clear spend data next to the services they own, InfraWallet provides a focused, practical path inside Backstage.
Installation Instructions
These instructions apply to self-hosted Backstage only.
Install the frontend package
- Add the package
yarn --cwd packages/app add @electrolux-oss/plugin-infrawallet
- Add the route so the page is visible
Edit packages/app/src/App.tsx
import React from 'react';
import { Route } from 'react-router';
import { FlatRoutes } from '@backstage/core-app-api';
import { InfraWalletPage } from '@electrolux-oss/plugin-infrawallet';
export const AppRoutes = () => (
<FlatRoutes>
{/* your other routes */}
<Route path="/infrawallet" element={<InfraWalletPage />} />
</FlatRoutes>
);
- Optional. Set a custom title or subtitle
<Route
path="/infrawallet"
element={<InfraWalletPage title="Cloud costs" subTitle="Across all providers" />}
/>
- Optional. Add a sidebar item
Edit packages/app/src/components/Root/Root.tsx
import React from 'react';
import { Sidebar, SidebarGroup, SidebarItem } from '@backstage/core-components';
import MenuIcon from '@material-ui/icons/Menu';
import { InfraWalletIcon } from '@electrolux-oss/plugin-infrawallet';
export const Root = ({ children }: { children?: React.ReactNode }) => (
<Sidebar>
{/* your other sidebar groups */}
<SidebarGroup label="Menu" icon={<MenuIcon />}>
<SidebarItem
icon={InfraWalletIcon}
to="infrawallet"
text="InfraWallet"
/>
</SidebarGroup>
</Sidebar>
);
InfraWallet will be available at path /infrawallet
Install the backend plugin
New backend system
- Add the package
yarn --cwd packages/backend add @electrolux-oss/plugin-infrawallet-backend
- Register the plugin in the backend
Edit packages/backend/src/index.ts
Add this before backend.start
// other imports and setup above
// InfraWallet backend
backend.add(import('@electrolux-oss/plugin-infrawallet-backend'));
backend.start();
Legacy backend system
- Add the package
yarn --cwd packages/backend add @electrolux-oss/plugin-infrawallet-backend
- Create a plugin router
Create packages/backend/src/plugins/infrawallet.ts
import { createRouter } from '@electrolux-oss/plugin-infrawallet-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
export default async function createPlugin(env: PluginEnvironment): Promise<Router> {
return await createRouter({
logger: env.logger,
config: env.config,
cache: env.cache.getClient(),
database: env.database,
});
}
- Wire it into the backend
Edit packages/backend/src/index.ts
// other imports
import infraWallet from './plugins/infrawallet';
async function main() {
// other setup
const infraWalletEnv = useHotMemoize(module, () => createEnv('infrawallet'));
apiRouter.use('/infrawallet', authMiddleware, await infraWallet(infraWalletEnv));
}
Configure frontend defaults
Add this to app-config.yaml if you want to change the default view
infraWallet:
settings:
defaultGroupBy: none # none by default, or account, provider, category, service, tag:<tag_key>
defaultShowLastXMonths: 3 # we recommend less than 12
Configure provider integrations
All provider credentials live under backend.infraWallet.integrations in app-config.yaml
AWS setup
Give the IAM role these permissions
{
"Statement": [
{
"Action": ["ce:GetCostAndUsage", "ce:GetTags"],
"Effect": "Allow",
"Resource": "*",
"Sid": ""
}
],
"Version": "2012-10-17"
}
Use one role in the management account to read all member accounts when you use AWS Organizations
If you do not use a management account then create the role in each account and set trust per account
Add the config
backend:
infraWallet:
integrations:
aws:
- name: my-aws
accountId: '123456789012' # quoted as a string
assumedRoleName: infrawallet-reader
accessKeyId: ${AWS_ACCESS_KEY_ID} # optional
secretAccessKey: ${AWS_SECRET_ACCESS_KEY} # optional
If accessKeyId and secretAccessKey are not set the SDK uses the default credential chain
Azure setup
- Register an app in Azure AD
- In the subscription grant Cost Management Reader to the app
- Create a client secret
Add the config
backend:
infraWallet:
integrations:
azure:
- name: my-azure
subscriptionId: ${AZURE_SUBSCRIPTION_ID}
tenantId: ${AZURE_TENANT_ID}
clientId: ${AZURE_CLIENT_ID}
clientSecret: ${AZURE_CLIENT_SECRET}
GCP setup
Export billing data to Big Query
Create a service account with roles BigQuery Data Viewer and BigQuery Job User
Create a JSON key file for that service account
Add the config
backend:
infraWallet:
integrations:
gcp:
- name: my-gcp
keyFilePath: /secure/path/gcp-key.json # mount as a file in your runtime
projectId: my-billing-project
datasetId: my_bq_dataset
tableId: gcp_billing_export
Confluent Cloud setup
Create an organization level API key with cloud resource management scope
Add the config
backend:
infraWallet:
integrations:
confluent:
- name: my-confluent
apiKey: ${CONFLUENT_API_KEY}
apiSecret: ${CONFLUENT_API_SECRET}
MongoDB Atlas setup
Create an organization API key with Organization Billing Viewer permission
Add the config
backend:
infraWallet:
integrations:
mongoatlas:
- name: my-mongoatlas
orgId: ${MONGODB_ATLAS_ORG_ID}
publicKey: ${MONGODB_ATLAS_PUBLIC_KEY}
privateKey: ${MONGODB_ATLAS_PRIVATE_KEY}
Multiple accounts example
backend:
infraWallet:
integrations:
azure:
- name: fin-team
subscriptionId: ...
tenantId: ...
clientId: ...
clientSecret: ...
- name: core-team
subscriptionId: ...
tenantId: ...
clientId: ...
clientSecret: ...
aws:
- name: dev
accountId: '123456789012'
assumedRoleName: ...
accessKeyId: ...
secretAccessKey: ...
- name: prod
accountId: '210987654321'
assumedRoleName: ...
accessKeyId: ...
secretAccessKey: ...
Category mappings
The plugin stores category mappings in the database
If the table is empty it seeds with defaults from plugins /infrawallet-backend/seeds/init.js
You can change that seed file or update the table later
Where you will see it
The page lives at /infrawallet
Use the sidebar item if you want quick access from the left menu
Changelog
This changelog is produced from commits made to the InfraWallet plugin since 5 months ago, and based on the code located here. It may not contain information about all commits. Releases and version bumps are intentionally omitted. This changelog is generated by AI.
Breaking changes
- #167 Rename AWS config key
accessKeySecret
tosecretAccessKey
. Update your config to keep things working. 3 months ago - #174 Disable autoload by default. If you rely on autoload you need to enable it in your config. 3 months ago
Features
- #189 Add budget datapoints and breakdowns on the budgets page. 1 month ago
- #186 Add extension point for EntityReports. The EntityInfraWalletCard can use custom entity data. 1 month ago
- #163 Add GitHub support. 4 months ago
Bug fixes
- #197 Fix schema validation for providers in non default setups. Add logging to help debug the transform step. Restore missing icons. 6 days ago
- #191 Fix number formatting in the cost graph. 1 month ago
- #188 Fix GCP cost fetching to avoid data loss on fetch errors. 2 months ago
Improvements
- #177 Improve UI loading for the entity card. 3 months ago
Security
- #173 Secure GitHub token handling for DevTools. 3 months ago
- #160 Fix scorecard vulnerabilities. 4 months ago
Documentation
- #183 Update docs. 3 months ago
- #182 Update Datadog doc. 3 months ago
- #175 Update README. 3 months ago
- #172 Add docs for Elastic Cloud. 3 months ago
- #195 Add PitchBook to adopters. 1 month ago
Dependencies
- #161 Upgrade Backstage and dependencies. 4 months ago
Set up Backstage in minutes with Roadie
Focus on using Backstage, rather than building and maintaining it.